まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

2018/04

恥ずかしながら、今回紹介する Linux の sc コマンドの存在を全くしりませんでした。。


sc(spreadsheet calculator) コマンドは UNIX/Linux のコンソールから使える表計算アプリケーションです。X Window で動作する GUI アプリではなく、あくまで CUI のコンソール上で動く表計算アプリケーションです。オッサン的には DOS 時代の Lotus 1-2-3 を彷彿とさせる画面に胸騒ぎを禁じえません:
2018042900


インストール方法はソースからビルドするものも含めて数通りありますが、Debian ベースの Ubuntu や Raspberry Pi であれば、apt-get コマンドを使って普通に導入できます:
$ sudo apt-get install sc

このコマンドを実行するだけで導入できます。私のラズパイで実行した時の様子がこちら↓です。コマンド実行前のライブラリの導入状況も含めた環境にも依存するとは思いますが、私の環境ではアプリケーション全体で 369 キロバイト( 0.37 メガバイト)しか使いませんでした。超軽量アプリです:
2018042901


インストール後、プロンプトで "sc" を実行すると起動します:
2018042902
 (↑ DOS 版 Lotus 1-2-3 を知っていると、この時点で感動の涙モノ)


起動後の使い方は '?' キーを入力することで参照できますが、ざっと調べた限りでカーソル移動を含めた主なものはこちらです。いわゆる vi エディタのコマンドに近い操作体系になっているので、vi 派であればすぐに使えるようになると思っています:

操作キー解説
カーソル移動(上下左右)方向キーまたは kjhlvi キーバインド
数値入力カーソル位置で = を入力してから数値を入力
文字入力カーソル位置で > を入力してから文字を入力
値の削除カーソル位置で x を入力vi キーバインド
足し算・引き算などカーソル位置で = を入力してからセルを指定して A0 + A1 のような式を入力
終了q


機能的に Excel と比較するようなレベルのものではありませんが、むかーし 1-2-3 の製品開発に関わっていた自分的にはノスタルジックを越えた何かを感じるツールです。

IBM Watson の比較的新しい API の1つである Watson Data Kit を使ってみました。ちなみにこのブログエントリを書いている 2018/Apr/28 の時点ではこの API はベータ版扱いとなっており、無料で利用できますが、ライトプランから利用することはできないようです。

この API は収集・解析済みのデータにアクセスすることができる API です。具体的にはある地点(緯度&経度)と調査半径(マイル)を指定すると、そのエリア内に含まれる観光名所やアトラクションをまとめて教えてくれる、というものです。特別に明記されているわけではないのですが、使っている限りでの印象として、現時点ではどうやら USA のデータ中心に提供されているようです。

使ってみるには IBM Cloud のダッシュボードから、「アプリケーション・サービス」カテゴリ内にある "Watson Data Kits" を選びます。 「Watson」カテゴリではなく「アプリケーション・サービス」カテゴリ内にあることに注意が必要です:
2018042800


そしてプランを選択してサービスを作成します。現時点では利用制限のない Free plan (無料)のみが提供されているようです:
2018042802


Watson Data Kit サービス作成後、サービス資格情報メニューから資格情報を(必要であれば作成した上で)参照します。この中の apikey と書かれている値と、instance-id と書かれている値が後で必要になります:
2018042803


これらの値を使って、以下のような Node.js のアプリケーションを作ってみました。(apikey) 部分と (instance-id) 部分を上記で取得した値に書き換えると動くようになる、と思います。また以下の例では米国ニューヨーク辺りの位置(北緯 40.73061 度、西経 73.935242 度)と、そこからの半径 5 マイル内のアトラクション( /attractions)を検索し、名称(name)と説明(description)を表示しています:

var request = require( 'request' );

var settings = {
  apikey: '(apikey)',
  instance_id: '(instance id)'
};

// NY
var lat = 40.73061;
var lng = -73.935242;

var radius = 5;  //. 半径 5 マイル

//. アクセストークン取得
var options = {
  url: 'https://iam.bluemix.net/identity/token',
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  form: { grant_type: 'urn:ibm:params:oauth:grant-type:apikey', apikey: settings.apikey },
  json: true
};
request( options, ( err, res, body ) => {
  if( err ){
    console.log( err );
  }else{
    var access_token = body.access_token; //. アクセストークン値

    //. アクセストークンを使って、/attractions API を実行する
    var access_headers = {
      'Authorization': 'Bearer ' + access_token,
      'Instance-ID': settings.instance_id
    };
    var access_options = {
      method: 'GET',
      hostname: 'wck-2.us-south.containers.mybluemix.net',
      port: null,
      uri: settings.apiurl + '/travel/v1/attractions?location=' + lat + ',' + lng + '&radius_miles=' + radius,
      headers: access_headers
    };
    request( access_options, ( err1, res1, body1 ) => {
      if( err1 ){
        console.log( err1 );
      }else{
        body1 = JSON.parse( body1 );
        body1.results.forEach( function( attraction ){
          console.log( attraction.name );
          console.log( ' ' + attraction.description );
        });
      }
    });
  }
});


上記を実行するためにまず apikey 値を使ってアクセストークンを取得し、取得したアクセストークンと instance-id 値を使って /attractions API を実行しています。この辺りの詳しい情報はチュートリアルを参照ください:

https://console.bluemix.net/docs/services/watson-data-kits/index.html#getting-started-tutorial


これを実行するとこんな感じになりました。青字部分が名称(name)で、黒地が説明(description)です:
$ node attractions.js
Calvary Cemetery
 Calvary Cemetery is a Roman Catholic cemetery in Maspeth and Woodside, Queens, in New York City, New York, United States. With about 3 million burials, it has the largest number of interments of any cemetery in the United States; it is also one of the oldest cemeteries in the United States. It covers 365 acres and is owned by the Roman Catholic Archdiocese of New York and managed by the Trustees of St. Patrick's Cathedral.
Calvary Cemetery is divided into four sections, spread across the neighborhoods of Maspeth and Woodside. The oldest, First Calvary, is also called "Old Calvary." The Second, Third and Fourth sections are all considered part of "New Calvary."
* First Calvary Cemetery is located between the Long Island Expressway and Review Avenue. The cemetery's offices are located here, at 49?02 Laurel Hill Boulevard.
* Second Calvary Cemetery is located on the west side of 58th Street between Queens Boulevard and the Brooklyn?Queens Expressway.
* Third Calvary Cemetery is located on the west side of 58th Street between the Long Island Expressway and the Brooklyn?Queens Expressway.
* Fourth Calvary Cemetery is located on the west side of 58th Street between the Long Island Expressway and 55th Avenue.
McCarren Park
 McCarren Park is a public park in Brooklyn, New York City. It is located in Greenpoint, Brooklyn and is bordered by Nassau Avenue, Bayard Street, Lorimer Street and North 12th Street. It is operated by the New York City Department of Parks and Recreation. Opened in 1906 and originally named Greenpoint Park, the park was renamed McCarren Park in 1909 after State Senator Patrick H. McCarren who began work as a cooper at Williamsburg sugar refineries and eventually became the Democratic boss of Brooklyn. The park is a popular destination for recreational softball, volleyball, soccer, handball, and other games. It is also used for sunbathing and dog-walking. In late 2004, the park's track was resurfaced and has been a popular destination for running enthusiasts.
Events on the baseball fields of McCarren Park include members of the punk and indie communities gathering to participate in league-controlled kickball tournaments. For several years, the baseball fields have hosted tournament play for the Hasidim; weekend afternoons provide T-ball and softball games for organized area youth groups; Latino families and friends often utilize the fields to play soccer and volleyball into the late hours of the night. Since June 2003, McCarren Park has hosted SummerScreen in McCarren Park, and The Renegade Craft Fair, a DIY event. The fair attracts artists and creative types, featuring a wide range of merchandise such as reconstructed clothing, comic books, tote bags and other handmade goods.
Pulaski Bridge
 The Pulaski Bridge in New York City connects Long Island City in Queens to Greenpoint in Brooklyn over Newtown Creek. It was named after Polish military commander and American Revolutionary War fighter Kazimierz Pu?aski because of the large Polish-American population in Greenpoint. It connects 11th Street in Queens to McGuinness Boulevard (formerly Oakland Street) in Brooklyn.
5 Pointz
 5 Pointz: The Institute of Higher Burnin' or 5Pointz Aerosol Art Center, Inc., mainly referred to as simply 5 Pointz or 5Pointz, was an American mural space at 45?46 Davis Street in Long Island City, Queens, New York City. When it opened in 1892, it housed the Neptune Meter factory, which built water meters.
   :
   :

位置情報サービスに対して、その周辺のアトラクションやキーワードとなる付加情報を加えることができるようになる、面白い API だと感じました。



業務の忙しさを言いわけに、IBM Cloud の新しい情報に疎くなっていました。で「なんか面白そうな API ないかなあ」とカタログを眺めていたら・・・

「金融」カテゴリに、、ん??
2018041901


こっ、これはっ!? もしやシグナイト!?
2018041902


おー、やっぱりシグナイトだ。世界中の株や為替を始めとする色々なマーケット情報を提供するシグナイトの API が IBM Cloud のサードパーティ API としても登録されていたのでした(知りませんでした、何か)。ただこの API はここからそのまま使えるわけではなく、別途アカウント登録が必要なようで、↓ひとつ進んだこのページの "Xignite" と書かれたリンクからアカウント登録に進みます:
2018041903


すると、この↓ページにジャンプします。ほうほう、シグナイト API は本来有料なのですが、IBM Bluemix(Cloud) ユーザー向けに7日間のトライアルが提供されている模様です:
https://market-data.xignite.com/IBM_Marketplace.html

2018041900


で、ここから名前やメールアドレスを指定して登録し、アドレスに届いたメールの内容を使って申請していきます。途中、以下のような画面になり、こんかいのトライアルで利用する API を1つ指定します(どうやらトライアルで利用できるのは一つだけのようで複数指定はできないようでした)。迷いましたが、個人的にも取引経験のある FX 向けの XigniteGlobalCurrencies を選択しました:
42


更に先に進み、アカウントのパスワードを指定してアクティベートします:
33


アクティベートが完了すると登録したアドレスに以下のようなメールが届きます。ここから "token" と書かれたリンクをクリックして、API 用のトークンを確認できます:
18


再びシグナイトのページに移動し、以下の赤枠部分に API 用のトークンが表示されています。API 実行時にこのトークン文字列が必要になります:
52


次にどんな API が提供されているのか調べてみます。シグナイトの API カタログページから今回選択した API(上記例の場合は XigniteGlobalCurrencies)を探し、その "API List" と書かれたボタンをクリックします:
26


すると指定した種類(XigniteGlobalCurrencies)の API 一覧が表示されます。ここでどんな API が存在して、どうすると実行できるのか、実際の実行結果がどんなフォーマットになるのか、といった情報を確認したり、実際に実行したりできます:
2018041904


試しにひとつ使ってみます。左側の API 一覧からリアルタイムレートを参照する GetRealTimeRate を選びます。すると画面右側が GetRealTimeRate 用に切り替わり、ここから各種パラメータを指定して実際に実行することができます(注 実行できるのはログイン時のみ)。以下の例では Request タブで
 Symbol: USDJPY(米ドル円レート)
 Result Format: JSON(結果を JSON で取得)
を指定しました。するとその下の URL が動的に切り替わり、この条件で API を実行する際のエンドポイント URL を示してくれます。下図ではモザイクをかけていますが、この URL にはトークンが含まれているので、そのままコピペ等で実際に確認することも可能な URL になっています。最後に下の "View Result" ボタンを押して実行します:
2018041905


成功すると実行結果が下部に JSON フォーマットで表示されます:
2018041906


実際の中身はこんな感じ、ほぼリアルタイムに値が取得できています(このタイミングで1ドルを買うと 107.374 円、売ると 107.368 円で、仲値が 107.371 円、という結果でした):
{
 "Outcome": "Success",
 "Message": null,
 "Identity": "Request",
 "Delay": 0.0167211,
 "BaseCurrency": "USD",
 "QuoteCurrency": "JPY",
 "Symbol": "USDJPY",
 "Date": "04/19/2018",
 "Time": "9:18:18 AM",
 "QuoteType": "Spot",
 "Bid": 107.368,
 "Mid": 107.371,
 "Ask": 107.374,
 "Spread": 0.006,
 "Text": "1 United States dollar = 107.371 Japanese yen",
 "Source": "SIX Financial Information"
}

トライアルだと7日間限定とはいえ、こんな便利な API が IBM Cloud から利用できるようになっていたんですねー。パラメータを変えて実行したり、他の API もここから同様に試すことができそうです。


なお、トライアルではない正式版(?)の API の価格については Flexible Pricing Model が適用されるようで、価格そのものはウェブからは確認できませんでした。興味ある方はこちらから問い合わせる必要がありそうです:
https://www.xignite.com/Pricing

 

大阪府吹田市が市内の観光名所をテーマにしたデザインマンホール3種を作成し、先日公開されました:
吹田市がデザインマンホール蓋3種類 楽しみながら探して

この3種は「三色彩道の紅葉」、「ガンバ大阪」、そして「大阪モノレール」をテーマにしたもので、設置場所についてはヒントだけが公開されていました。ちょうど万博公園の「太陽の塔」の内部公開を見に行くタイミングと重なったので、この3つを探してきました。そしてそれぞれマンホールマップに投稿したので、以下は結果的に場所のネタバレを含む内容になっています(苦笑)。

















まず1つ目、「三色彩道の紅葉」


これは阪急千里線「北千里」駅からテーマになっている「三色彩道」に向かって歩いた途中の保育園の近くで見つけました。
http://manholemap.juge.me/page.jsp?id=5607739796554497828



2つ目、「ガンバ大阪」、ガンバのマスコットであるガンバボーイと、吹田市のイメージキャラクター「すいたん」がサッカーで共演しているマンホールです:



これは当然パナソニック吹田スタジアム・・・かと思いきや、結構難問でした。結論として最寄り駅は大阪モノレール公園東口駅で、ここから吹田スタジアムに向かって南下し、中国自動車道をくぐった直後の植え込みの中に設置されていました。↑の写真を見ると周囲が植え込みっぽくなっていることがわかると思います。

http://manholemap.juge.me/page.jsp?id=6283324744500361540



そして3つ目、「大阪モノレール」



こちらは大阪モノレール万博記念公園駅から東のららぽーとに向かって歩きます。そしてららぽーとに入るのではなく、万博記念公園に向かう橋も渡らず、ららぽーとの北側にある、モノレールと並行して伸びる側道(自転車の駐輪場? ちょっとわかりにくい)に入ります。そして入ってすぐの所に設置されていました。発見難易度はこれが一番難しかったと思います。

http://manholemap.juge.me/page.jsp?id=1433437503660013763


ちなみに、2番目のガンバマンホールに万博記念公園駅から向かう場合、この3番目のマンホールが設置されている側道をそのまま東に向かって歩き続けることで最短距離で移動できます(ららぽーとに入ったり、ぐるっと廻って吹田スタジアム経由で向かおうとすると手間取ることになります)。



なお、これら3種すべてのマンホールに suitable city という文字が表記されています。この "suitable city" を直訳すると「適度な市」とか「ちょうどいい市」みたいな感じだと思いますが、同時に suita(吹田)という部分が強調されていて、ダジャレマンホールになっています。こんなオチを隠し含めるあたりは大阪の意地なんでしょうかね。。。


吹田を訪ねる予定があり、これらのマンホールを探したいけど、滞在時間の関係などでどうしても効率よく周りたい、という方は参考にしてください。 (^^;


自分メモ兼情報緩募なブログエントリです。

SSH でサーバーにリモートログインして作業している途中で通信が途切れてしまう(プロセスが死んでしまうわけではなく、通信が切れてしまう)ケースがあります。自分が比較的頻度高くやっちゃうのは、電車内からテザリングを使ってリモートログインした先で Node.js のサーバーを動かしていて、地下鉄に入って通信が遮断しちゃうケースです。

これをやってしまって困るのは、例えば Node.js のサーバーを 8000 番ポートで動かしていたとすると、8000 番ポートへの listen が生きたままの状態で通信が切れてしまうことです。繋がっていれば Ctrl+C でサーバーを落とすことができるのですが、繋がっていないので Ctrl+C を入力する端末がありません。ということは再度リモートログインしてプログラムを修正して再度実行・・・しようとしても「そのポートは使われています」エラーになってしまいます。なんとかして元のプロセスを止めなければなりません。


※余談ですが、本来はこうならないように(途中で通信が切れてしまうことを想定して) screentmux などの端末のマルチプレクサーを使って作業するべきです。ただ今回はマルチプレクサーを使っていない時にこうなってしまった場合の対処方法についての話です。


以下で紹介する方法が正解かどうかはわからないのですが、自分の対処方法を紹介します。考え方としては「プロセスが残っているはずの SSH を探し出して息の根を止める」というアプローチです。

というわけで、まずは再度リモートログインした先で ps コマンドを実行して、自分が所有しているプロセスを一覧表示します(ちなみに実行コマンド内で `whoami` を実行していますが、自分の環境だとこの結果は dotnsf となり、dotnsf という文字を含むプロセスの一覧を表示しています):
$ ps -aux | grep `whoami`

root      4335  0.0  0.0  94924  7092 ?        Ss   08:19   0:00 sshd: dotnsf [priv]
dotnsf    4410  0.0  0.0  94924  4428 ?        S    08:20   0:00 sshd: dotnsf@pts/8
dotnsf    4411  0.0  0.0  23912  5620 pts/8    Ss   08:20   0:00 -bash
dotnsf    4654  0.0  0.5 935364 41736 pts/8    Sl+  08:37   0:00 node app
root      5167  0.0  0.0  94924  6964 ?        Ss   09:20   0:00 sshd: dotnsf [priv]
dotnsf    5243  0.0  0.0  94924  3408 ?        S    09:20   0:00 sshd: dotnsf@pts/9
dotnsf    5244  0.1  0.0  23800  5392 pts/9    Ss   09:20   0:00 -bash
dotnsf    5270  0.0  0.0  38376  3392 pts/9    R+   09:21   0:00 ps -aux
dotnsf    5271  0.0  0.0  15256  1012 pts/9    S+   09:21   0:00 grep --color=auto dotnsf
dotnsf   23891  0.9  1.4 1661748 118288 ?      Sl    2月23 651:40 /opt/couchdb/bin/../erts-7.3/bin/beam.smp -K true -A 16 -Bd -- -root /opt/couchdb/bin/.. -progname couchdb -- -home /opt/couchdb -- -boot /opt/couchdb/bin/../releases/2.0.0/couchdb -kernel inet_dist_listen_min 9100 -kernel inet_dist_listen_max 9100 -kernel error_logger silent -sasl sasl_error_logger false -noshell -noinput -config /opt/couchdb/bin/../releases/2.0.0/sys.config
dotnsf   23940  0.0  0.0   4512   856 ?        Ss    2月23   0:00 sh -s disksup
dotnsf   23941  0.0  0.0   4232    72 ?        Ss    2月23   0:05 /opt/couchdb/bin/../lib/os_mon-2.4/priv/bin/memsup
dotnsf   23942  0.0  0.0   4364    76 ?        Ss    2月23   0:00 /opt/couchdb/bin/../lib/os_mon-2.4/priv/bin/cpu_sup
dotnsf   26173  0.0  0.0  45276  3140 ?        Ss    2月15   0:00 /lib/systemd/systemd --user
dotnsf   26174  0.0  0.0 210940  2152 ?        S     2月15   0:00 (sd-pam)
dotnsf   31713  0.0  0.0  11140   312 ?        Ss    3月30   0:00 ssh-agent
  (↑青字が実行コマンドです)


結果の中で注目すべきは赤字にした2行です。dotnsf が sshd から pts(仮想端末)を使っているプロセスが(左から2列目の数値でいうと) 4410 と 5243 の2つあります(実際にコマンドを実行した結果は3つ以上みつかるかもしれません)。この2つのうち、どちらかは今自分がリモートログインに使っている仮想端末のプロセスで、もう1つは今回のターゲットとなる行方不明のプロセスです。このどちらか正しい方のプロセスを kill することで目的を達成することができます。

というわけで、「どちらかは正解、間違えると自分が死ぬ」という下図のような状況なわけです(笑):
jigenbakudan_kaitai_shifuku




ここでの問題は「どちらが目的のプロセスかを判断する方法」なのですが、これって正解あるんでしょうか? (^^; 明確な方法があったら自分も知りたいです。

自分がやっている判断方法としては2つあります:
・時刻(左から9列目)を見る。どちらかは自分がログインしているプロセスということは、そのプロセスの時刻は自分がログインした時刻になっているので、自分が現在ログインしているプロセスをなんとなく判断できる。
・プロセス番号(この例だと 4410 と 5243)は大抵小さい方が古い。現在のログインに使っているプロセスの方が新しいはず。


で、この基準で考えるとプロセス番号 5243 の方が現在使っているプロセスに該当するので、もう1つの 4410 のプロセスが息の根を止めるべきプロセス、と判断できることになります。ただこの考え方は経験的なもので、もしかすると別の確実な方法があるかもしれません(誰か知っていたら教えてください)。


(↓追記)
who コマンドで自分が現在いる TTY を調べることができる、という指摘をいただきました。確かに使えそうです。
$ who
dotnsf   pts/8        2018-04-12 21:00 (192.168.X.X)

(↑追記)


というわけで、4410 を kill することにします:
$ kill 4410

まあ仮に間違えていたとしても自分が強制ログアウトされるだけなので、そしたらもう一度リモートログインしてもう1つの方を kill し直せばいいんですけどね。。

で、これで上手く元のプロセスを消すことができていれば、再度実行した時に「そのポートは使われています。。」エラーは消える、はず。

 

このページのトップヘ