パスワードなしの公開鍵認証でssh接続
expectで対話型シェルでは、bashの中でexpectスクリプトを読み込ませていますが、このサンプルには以下のような弱点があります。
これらをクリアするために、ssh-agentで公開鍵を生成して、パスワードなしでsshが使えるようにしておきます。
1. 鍵の生成
以下のコマンドで鍵を生成します。
ssh-keygen -t rsa
-tは、暗号方式を指定しています。
Enter file in which to save the key (/home/username/.ssh/id_rsa):
デフォルトでは、ホームディレクトリの.ssh以下に生成されます。何も入力せずエンターを押せばデフォルトを受け入れます。
次に、パスフレーズを訊かれるので、
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
何も入力せずエンターを押すと、パスワードなしで接続可能な設定になります。
.ssh以下に、鍵が生成されます。
Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xxxx:xx:xx:xx:xx:xx:xx:xx username@hostname
シェルスクリプトで配列へのpush/pop
配列listに値varをpush
n=${#list[@]} list[$n]=$var
配列のサイズを添字として、新たな要素を追加しているだけ。シェルスクリプトの配列のインデックスは0からです。
問題は、popです。
配列listから値varをpop
n=`expr "${#list[@]}" - 1` var=${list[$n]} unset list[$n] list=${list[@]}
"unset"は、配列の指定した要素を削除します。しかし、同時にインデックスは削除されず、空要素として残ってしまいます。
そのため、最後に別の配列に入れ直して、リセットする必要があります。
ATNDで, 気になるイベントをメールで通知させる
今年は社外の勉強会に定期的に行く、と上司と1年前に約束したことをふと思い出し、最近になって勉強会に出向くようになりました。イベント探しによく利用するのはご存知ATNDです。
しかし、たまに思い出したときに気になるキーワードで検索をかけてみると、いい感じのイベントがすでに定員オーバーになっている、ということも少なくありません。
そこで、あらかじめ登録したキーワードにマッチするイベントを、メールで通知してくれるアプリを書いてみました。
ATNDのJava APIはここから落とせました。 => http://atnd4j.sourceforge.jp/
commonsのSimpleEmailを使って、Gmailのsmtpサーバーから送ってます。
汚いけど許してね...
package jp.boc.com; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.SimpleEmail; import org.hkzo.atnd4j.Atnd; import org.hkzo.atnd4j.Event; import org.hkzo.atnd4j.EventsResult; public class EventNotifier { public static void main( String args[] ){ EventNotifier ntfr = new EventNotifier(); List<String> list = new ArrayList<String>(); list.add( "kvs" ); list.add( "nosql" ); list.add( "デザインパターン" ); String query = ntfr.createQuery( list ); ntfr.sendMail( query ); } private String createQuery( List<String> keywords ){ StringBuffer sb = new StringBuffer(); sb.append("keyword_or="); for ( String s : keywords ) { sb.append(s + "," ); } return sb.toString(); } private void sendMail ( String query ) { org.apache.commons.mail.SimpleEmail se = new SimpleEmail(); try { se.setCharset( "utf-8" ); se.setHostName( "smtp.gmail.com" ); se.setSmtpPort( 587 ); se.setTLS( true ); se.setAuthentication( "username", "password" ); se.addTo( "送り先アドレス" ); se.setFrom( "gmailアドレス" ); se.setSubject( "気になるATNDイベント" ); StringBuilder msgBldr = new StringBuilder(); for( Event event : getEvent( query ) ) { msgBldr.append( "★ " + event.getTitle() + " " + event.getStartedAt() + " @ " + event.getAddress() + "\n" + " " + event.getCatch() + "\n\n"); } se.setMsg(msgBldr.toString()); se.send(); } catch ( EmailException eme ) { eme.printStackTrace(); } } private List<Event> getEvent( String query ) { Atnd atnd = new Atnd(); EventsResult res = null; try { res = atnd.getEvents( query ); } catch ( IOException ioe ) { ioe.printStackTrace(); } List<Event> list = res.getEvents(); return list; } }
とこんな感じのものを、クーロンから3日に1回くらい叩きたいわけです。
問題は置いておくサーバがないということと、たった今、"ATND Notifier"という素晴らしいChrome Extensionを見つけてしまったため、このアプリの存在価値がなくなってしまったことでしょうか。。
Pythonで設定ファイルから値の読み込み (ConfigParser)
この記事はちょっと古いので書き直しました。
lake-michigan.hatenablog.com
Excel2007で簡単ヒストグラム
Excelでびっくりするほど簡単にヒストグラムが作成できます。とても便利なのに、知らんかった・・・のでメモ。
- 準備(アドインのインストール)
- Officeボタン > Excelのオプション > アドイン > 設定 > 分析ツール にチェックし、インストール
- データタブに、「分析」カテゴリが登場する
- 実行
- 「分析」カテゴリの「データ分析」をクリック
- 「ヒストグラム」をクリック
- 「入力範囲」に対象データ範囲を指定
- 「データ区間」(グラフの横軸にあたる)も指定可能だが、空欄だと入力範囲に合わせて等間隔で区間が刻まれる
- グラフ作成 にチェックして、OKをクリックすると、別シートにグラフが生成されます
ありがとう、Excelさん。
expectで対話型シェル
sshやscpなど、対話型のインプットが必要なコマンドを、スクリプト化して運用に使いづらいので、expectパッケージを利用すると便利です。
OSにあらかじめexpectのパッケージが入っていない場合、下記コマンドでインストール。
yum install expect
下記は、リモートホストにログインして ls を叩くシェルのサンプルです。
#!/bin/bash hostname=192.168.10.12 username=hoge password=hogehoge expect -c " spawn ssh -l oracle $hostname expect \"$username@$hostname's password:\" { send \"$password\n\" } \"Are you sure you want to continue connecting (yes/no)?\" { send \"yes\n\" expect \"$username@$hostname's password:\" send \"$password\n\" } expect \"\[$username@$hostname ~\]$\" send \"ls\n\" interact "
ポイントはこれだけ
- spawn 最初に投げるコマンド(別プロセスを生成)
- expect 予想される表示内容(パターンマッチが使える)
- send 表示内容に対して送りたいコマンド(改行文字を忘れずに。)
- expect "A" { send "B" } "A'" { send "B'" } と場合分けが可能
このサンプルでは、はじめてssh接続するホストの場合、~/.ssh/known_hosts に公開鍵登録の可否を聞かれるので、その表示が出るときと出ないときを場合分けしてます。
ROWNUMで結果のレコード数を制限する
あるカラムでソートした結果の、上位n件だけを抽出したい・・・というときに便利な
LIMIT句というものがあります。
select * from EMPLOYEES order by EMPLOYEE_ID asc limit 10;
これで、EMPLOYEE_IDのトップ10件のみ取得できます。
しかし、悲しいことにOracleではLIMIT句がサポートされていない・・・
代替として ROWNUM擬似列なるものを使って取得する必要があります。
ROWNUMとは、ある結果のセットに、仮想的なレコード番号を振ったものです。
このROWNUMを条件句にセットし、結果を制限します。
上記SQLと同様のことがしたい時は、以下のような感じになります。
select * from ( select rownum rn, s.* from ( select * from EMPLOYEES order by EMPLOYEE_ID ) s ) a where a.rn <= 10 order by a.rn;
注意点として、rownumは、直接where句やorder by句に指定できないので、
わざわざ入れ子にして別名をつける必要あり。ジャマくさいわね。