2012/10/31
hbstudy まとめ
先日参加した hbstudy #38 ハンズオンの
課題 の幾つかを
シェルのみ 縛りで回答してみる。
流石にシェルのみで解く場合はワンライナーは無理なので、
普通のシェルスクリプトの型式で記述している。
- 問題1: ユーザの抽出
-
/etc/passwd から、ユーザ名を抽出したリストを作って下さい
1IFS=: 2while read id other 3do 4 echo ${id} 5done </etc/passwd
IFS を : に変更して /etc/passwd を 直接フィールド分割して変数 u に read している。
- 問題2: ユーザの抽出
-
/etc/passwd から、次を調べて下さい。
ログインシェルが bash のユーザと sh のユーザどちらが多い?
1IFS=: 2while read id p u g e d shell 3do 4 case ${shell} in 5 */sh ) 6 sh=$((${sh} + 1));; 7 */bash ) 8 bash=$((${bash} + 1));; 9 esac 10done < /etc/passwd 11echo "bash: " ${bash} 12echo "sh: " ${sh}
問題:1 同様に IFS を : に変更して /etc/passwd を直接フィールド分割して 変数 u、shell に read し、 変数 sh と bash に出現回数をカウントしている。
- 問題5: FizzBuzz
-
1,2,3,4,5…と数えていって…
- 3 の倍数だったら数字の代わりに「Fizz」
- 5 の倍数だったら数字の代わりに「Buzz」
- 15 の倍数だったら数字の代わりに「FizzBuzz」
1i=1 2while [ ${i} -lt ${1:-100} ] 3do 4 if [ $((${i} % 15)) -eq 0 ] 5 then 6 echo -n "FizzBuzz," 7 elif [ $((${i} % 5)) -eq 0 ] 8 then 9 echo -n "Buzz," 10 elif [ $((${i} % 3)) -eq 0 ] 11 then 12 echo -n "Fizz," 13 else 14 echo -n "${i}," 15 fi 16 i=$((${i} + 1)) 17done 18echo
素直に 1 から $1 (指定されていない場合は 100) までを $((…)) にて % 演算子で剰余計算して出力している
- 問題8: CPU 使用率
-
top の出力からどのユーザが
何% CPU を使用しているか集計して下さい。
1exec 3<&0 0<< EOF 2`ps aux` 3EOF 4 5while read u p c other 6do 7 if [ "${u}" != "USER" ] 8 then 9 case ${users} in 10 *${u}* ) 11 ;; 12 * ) 13 users="${users} ${u}" 14 ;; 15 esac 16 eval "$u=\$((\$$u + ${c%%.*}))" 17 fi 18done 19 20for i in ${users} 21do 22 echo "${i} : `eval echo '$'$i`" 23done
CPU 使用率は小数点以下切り捨てで計算している。
出現したユーザID を users 変数に格納しておく。
eval と $((…)) を利用して、 ユーザID を変数名とした変数に CPU 利用率を集計している。
最後に for ループで users に格納された ユーザID とユーザIDを変数名とした変数に格納されている 集計値を表示している。
FreeBSD では top -b -n 1 が利用不可なので ps aux の出力を集計する
全てのスクリプトは FreeBSD 上の /bin/sh で動作確認済み。
手元に Linux 環境が存在しないので Linux での動作は未確認だけど、
posix 機能だけしか使用していない(筈)なので Linux でも動作すると思う。
2012/10/30
2012/08/27
2012/08/12
行き当たりばったり
折角の新車なのでドライブでも…と早朝 5 時に起床して出発。
新東名の駿河湾沼津 SA のリサとガスパールのカフェに行ってみたいので、
とりあえず本栖湖を目的地に設定し朝 6 時に出発する。
が、しかし既に東名高速は渋滞している様で、
VICS 信号を受信したナビは鶴川方面を通過して
高尾山の辺りから中央高速経由のルートを指示してくる。
ナビに従って走り続けると殆ど渋滞もしていない中央高速から
朝 9 時には河口湖に到着してしまう。
折角河口湖に早い時間に到着したので当初の目的をすっかり変更し
白鳥のボートなどに乗りつつ河口湖を満喫してると空腹になってきたので、
以前何度か行った山中湖のレストランに向かう事にする。
山中湖に向かうと丁度ランチタイムに無事到着。
別荘地の森の中にある隠れ家の様な燻製レストランの
とっても気持ち良いテラスで美味しいランチを楽しんでいると
気持ちはすっかり泊まりたいモードに…
お盆休みの始まる週末に空き室なんかある宿がある訳ないだろうと思いつつ
レストランのご主人に聞いてみた所、
偶然空いているペンションを紹介していただけたので計らずも宿が決定。
宿が決まったので安心して 3 人乗り自転車で山中湖を堪能したり、
温泉にのんびりつかったりと山中湖も満喫。
夕食はアメリカン風のコース料理だったのだが、
スターターからセンス良い味付けで最後まで大満足。
翌日は当初の目的通り本栖湖を経由して新東名高速へ。
念願のリサとガスパールカフェに立ち寄って軽く食事をして自宅へ。
行き当たりばったりで日帰りドライブの予定で出かけた筈なのに、 殆ど渋滞らしい渋滞にも遭遇せずに とっても充実した一泊の家族旅行が楽しめました。
家族一緒だと とっても楽しいね☆
2012/08/04
2012/08/03
2012/08/01
キーボードショートカットのカスタマイズ
Mac では システム環境設定 → キーボード →
キーボードショートカット から
アプリケーション毎、もしくはシステム全体で有効な
キーボードショートカットが独自に作成できる。
この機能を利用するとメニューに項目があるが
ショートカットキーが定義されていない機能に
独自のショートカットキーが簡単に定義できるので非常に便利だ。
但し登録できるショートカットキーに制限があり
スペースやバックスペースなどは登録できないので、
KeyRemap4MacBook
を組み合わせて利用する事で任意のショートカットが利用できる様に設定する。
例えば プレビュー では ツール メニューから
水平方向に反転 や 垂直方向に反転 などの機能が利用できるが、
これらの機能には標準ではショートカットが定義されていない。
そこで前述の キーボードショートカット 機能を利用して
プレビュー に 水平方向に反転のショートカットや、
垂直方向に反転のショートカットを
コントロールやシフトなどとの組み合わせで指定する。
ここでは 水平方向に反転 は コマンド+シフト+H、
垂直方向に反転 は コマンド+シフト+V を登録したとする。
ショートカットが登録できたら プレビュー を起動して
指定したショートカットが正しく動作するか確認しておく。
次に KeyRemap4MacBook でスペースを コマンド+シフト+H に、
バックスペースを コマンド+シフト+V に置き換える設定を行えば、
スペースやバックスペースなどでショートカットが実行可能になる。
この時、キーの置き換えは特定のアプリケーション
(今回は プレビュー)だけに限定すると良いだろう。
そのためには KeyRemap4MacBook の Misc & Uninstall から
Open private.xml をクリックして以下の設定を追加する。
1<?xml version="1.0"?> 2 <root> 3 <!-- アプリケーション "プレビュー" の定義 --> 4 <appdef> 5 <appname>PREVIEW</appname> 6 <equal>com.apple.Preview</equal> 7 </appdef> 8 9 <!-- "プレビュー" に対するキーマッピングの定義 --> 10 <item> 11 <name>Preview Key</name> 12 <identifier>private.PreviewKeys</identifier> 13 <only>PREVIEW</only> 14 <!-- スペースはコマンド+シフト+H に置換 --> 15 <autogen>--KeyToKey-- KeyCode::SPACE, KeyCode::H, ModifierFlag::COMMAND_L | VK_SHIFT</autogen> 16 <!-- バックスペースはコマンド+シフト+V に置換 --> 17 <autogen>--KeyToKey-- KeyCode::DELETE, KeyCode::V, ModifierFlag::COMMAND_L | VK_SHIFT</autogen> 18 </item> 19 </root>これらの設定を追加する事で プレビュー 上では スペースは コマンド+シフト+H に置換されてアプリケーションに 通知されるので、 登録したショートカット(水平方向に反転)が実行される事になる。
2012/07/27
シェルスクリプトで便利な小技
シェルスクリプトを作成するときに知っておくと便利な小技集。
- exec > ファイル
-
以降の標準出力を全て ファイル に出力するので
この設定をしておくと簡単な実行ログが取得出来る。
同様に exec 2> ファイル とすると 標準エラー出力が全て ファイル に出力されるので エラーログが取得できる。
当然 exec > ファイル 2>&1 とすれば 標準出力も標準エラー出力も取得できる。
ファイル に /dev/null を指定すれば スクリプト実行中の出力は全て抑止されるので、 cron (8) から実行される場合などでは便利な場合もある。
1#!/bin/sh 2 3exec 2> ${TMP:-/tmp}/myname.log 4 :
- set -e
-
スクリプト実行時に制御文以外でエラーが発生した場合に
スクリプトを終了させる。
スクリプト中で実行すべきコマンドを typo した場合などで、 以降の処理が実行されると困る場合などに特に役立つ。
1#!/bin/sh 2 : 3echo "call myfunc ..." 4mtfunc # 関数名を typo している 5echo "end myfunc ..." 6 :
この様なコードの場合 set -e されていると、 mtfunc がエラーになった時点でスクリプトが エラー終了するので以降の処理が実行されない。
当然 if、while 、&&、 || などでコマンドの結果が評価される場合は エラーにはならない。 - set -u
-
スクリプト中で値が設定されていない変数を参照した場合に
エラーメッセージを表示してスクリプトを終了させる。
シェル変数や環境変数を typo した場合など、 変数に値が設定されていない事で発生する問題が回避できる。
1#!/bin/sh 2tempdir=/var/tmp/ 3mynam=myname 4 : 5rm -rf ${tmpdir}/${myname} # 変数名を typo している 6 :
この様なコードの場合、 変数名 ${tempdir} と ${mynam} を それぞれ typo しているので、 結果として rm -rf / に展開されてしまうが、 set -u されていると実行が防げる。 - set -n
- こちらはどちらかと言うとスクリプトの開発時に有効な設定で、 コマンドは実行されないのでスクリプトの文法チェックに最適。
- set -x
-
こちらも開発時に有効な設定で、
コマンドが実行される前にコマンドを stderr に出力する。
上の exec と組み合わせると 詳細な実行ログが取得できるのでデバッグに便利1#!/bin/sh 2 3exec 2> ${TMP:-/tmp}/debug.log 4set -x 5 :
2012/07/23
英辞郎の辞書をコマンドラインから参照してみる
英単語の意味を調べるのに man(1) を使ってしまう人に贈る1行 という記事を拝見して、
自分の FreeBSD マシンで英辞郎の辞書を参照している方法を記事にしてみる。
要は英辞郎の辞書を EPWING 型式に変換して
ndt サーバ経由で ndtpc コマンドから検索しているだけで、
検索コマンド自体は 1 行だが多少準備が必要となる。
- 英辞郎、和英辞郎、略辞郎、音辞郎の辞書を変換する。
-
英辞郎の辞書を EPWING 型式に変換するのは ports を利用すれば
何の問題もなく可能だ
(若干ディスク容量が必要だが、
今となっては問題とならない容量だと思う)。
作業は英辞郎の CD-ROM をマウントした状態で実施すれば良いのだが、 CD-ROM は I/O が遅いのでローカルのファイルシステムに 辞書ファイルをコピーして実行しても良い。
ローカルにファイルをコピーした場合は DICT_PATH で 英辞郎の辞書ファイルのパスを指定すれば良い。# cd /usr/ports/japanese/eijiro-fpw # make DICT_PATH=辞書ファイルのパス install clean # cd /usr/ports/japanese/waeijiro-fpw # make DICT_PATH=辞書ファイルのパス install clean # cd /usr/ports/japanese/ryakujiro-fpw # make DICT_PATH=辞書ファイルのパス install clean # cd /usr/ports/japanese/otojiro-fpw # make DICT_PATH=辞書ファイルのパス install clean
この変換作業は結構時間が必要である。 - ndtpd をインストールする
-
ndtpd は EB や EPWING などの辞書型式に対応している辞書サーバで、
FreeBSD では ebnetd という ports から導入可能である。
ports から導入すると ndtpd 以外に ebnetd、ebhttpd が インストールされるが今回は ndtpd のみ利用する。
# cd /usr/ports/japanese/ebnetd # make install clean # vi /usr/local/etc/ebnetd.conf # cat << EOF >> /etc/rc.conf > ndtpd_enable="YES" > EOF # chown nobody:nobody /var/run/ebnetd # /usr/local/etc/rc.d/ebnetd.sh start
ebnetd.conf はコメントを参照にすれば簡単に設定できる。 今回はローカルサーバの自分しか利用しないので、 接続ホストや接続数を制限した。### Port number `ndtpd' binds. ndtp-port ndtp ### Owner of the server process. user nobody ### Group of the server process. group nobody ### How many clients can be connected to the server at the same time. max-clients 1 ### Which hosts can or cannot connect to the server. hosts 127.0.0.1 ### Timeout seconds until the server disconnects an idle connection. timeout 900 ### Path to a working directory. work-path /var/run/ebnetd ### How many hit entries the server tries to find at a search. max-hits 50 ### The maximum size of text the server may send as a response to a client. max-text-size 32768 ### Syslog facility syslog-facility local0 ### ### Book entry ### begin book ### Name of the book. name eijiro ### Title of the book. title eijiro ### Path to a top directory of the book. path /usr/local/share/dict/eijiro-fpw ### How many clients can access the book at the same time. max-clients 1 ### Which hosts can or cannot access to the book. hosts 127.0.0.1 end begin book # # 以下 waeijiro の設定 # end begin book # # 以下 ryakujiro の設定 # end begin book # # 以下 otojiro の設定 # end
- 作成された辞書を ebzip で圧縮する
-
EB ライブラリで使用されている圧縮方式で、
辞書のためのディスク容量を多少なりとも削減するために辞書を圧縮する。
# cd /usr/local/share/dict/eijiro-fpw # ebzip --level 5 # cd /usr/local/share/dict/waeijiro-fpw # ebzip --level 5 # cd /usr/local/share/dict/ryakujiro-fpw # ebzip --level 5 # cd /usr/local/share/dict/otojiro-fpw # ebzip --level 5
- ndtpc をインストールする
-
ndtpc は perl で書かれた NDTP クライアントで、
こちら
で公開されているので利用する。
今の所 FreeBSD の ports にはなっていない様なので、 ソースを取得してインストールする。$ fetch http://www.tanu.org/~sakane/download/ndtpc-20050323a.tgz $ tar -C /usr/local/src -zxvf ndtpc-20050323a.tgz $ ./configure # make install
これで以下のコマンドラインで辞書検索が可能になる。
$ ndtpc hello DICT: 英辞郎 <4c33:560>hello hello 【発音】helo'u 【変化】《複》hellos [間投] こんにちは, あのう, やあ <4c33:5f0>hello Hello [人名] エロ DICT: 和英辞郎 DICT: 略語辞典 DICT: 音辞郎ちなみに jvim の keywordprg に ndtpc を登録すると 単語の上で 'K' をタイプする事で辞書を検索できるので便利。
2012/07/12
久々の迷惑メイル
先ほど携帯に届いた迷惑メイル。
やりくちがあまりにも下衆なので修正なしで晒す。
From: info@wu30oa22rs81rr.infoFrom アドレスや本文に書かれているの URL のドメイン部分が 怪しさ満点な wu30oa22rs81rr.info だったり、 URL の中に無理矢理入れた sagawa の文字だったり、 レターバック 等という低脳としか思えない間違いだったり etc. … 普通の人は引っかかる事はないと思いますが 注意喚起の意味をこめて公開します。
To: XXXX@docomo.ne.jp
Date: 2012/ 7/12 18:30
Subject: ※レターバック※宛先不明により集中センター保管中※受け取り先ご確認をお願い致します
現在、お客様宛のレターメールをお預かりしております。
配送先のご確認が必要となっておりますのでお手数ではございますが、下記よりアクセスの上、配送確認をお願い致します。
本メール配送便に関しまして、お届け先不着の状態ですとお届けが出来ませんのでご注意下さいませ。
http://wu30oa22rs81rr.info/XXXXXXXXXXXXXXXXXXXXXX/1307240/sagawa/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
そもそもレターパック(バック?)を騙るなら sagawa じゃなくて japanpost だろうと思うのだが…、 というかレターバッグって郵便配達の方が持っている鞄か?。
一生懸命にそれっぽく作ろうとしている努力は認めなくもないが、 文章の端々からにじみ出す本当の意味での頭の悪さを思うと 人ごとながら同情を禁じ得ない。
最近のドコモの携帯はメイル表示画面から迷惑メイルの報告ができる様なので、 勿論通報しておいた。