別に火は吹かないid:auientによるshell tips
id:naoyaさん、id:wadapさんのshell tipsの記事が話題になっていたので、便乗して自分もtipsを書いてみようと思います。
シェル操作編
$_で直前の引数を参照する
[nt@localhost] $_で一つ前のコマンドの最後の引数を参照できます。argv[argc-1]になるようです。これはクソ長い名前のディレクトリを作ってcdするときなどに便利です。
[nt@localhost] $ mkdir -p very/long/path/or/confusing_name_directory/20140426 [nt@localhost] $ cd $_ [nt@localhost] $ pwd /home/nt/very/long/path/or/confusing_name_directory/20140426 [nt@localhost] $
irbや確かpythonでも _ で最後の戻り値を参照できますね。いつからある機能なのか知りませんが、ここら辺から来てる慣習のような気がします。
!!で直前のコマンドを実行する
!!が一つ前のコマンドに展開されます。別にヒストリーを1つ戻っても同じですが、同じコマンドをsudoするときにドヤ顔できます。
[nt@localhost] $ service httpd restart Error: Permission denied [nt@localhost] $ sudo !! sudo service httpd restart [nt@localhost] $
Ctrl-z、jobs、fg、bgでジョブを自在に操る
Ctrl-zで現在のプロセスを中断できる、というのが紹介されていました。ならばjobsとfgとbgもセットで覚えてしまいましょう。
[nt@localhost] $ vi foo.rb # viの中でCtrl-zを押すとシェルに戻れる [1]+ Stopped vim foo.rb [nt@localhost] $ [nt@localhost] $ tail -f php_error_log # tail -f でも同じ ^Z [2]+ Stopped tail -f php_error_log [nt@localhost] $ [nt@localhost] $ make -f large_program.mak # 長ーいコンパイル中もOK ^Z [3]+ Stopped make -f large_program.mak [nt@localhost] $
確認するにはjobsコマンドを使います。これで現在のジョブが一覧表示されます。
[nt@localhost] $ jobs [1] Stopped vim foo.rb [2]- Stopped tail -f php_error_log [3]+ Stopped make -f large_program.mak [nt@localhost] $
元に戻るにはfgコマンド(fore ground)を使います。引数なしで直前のジョブ、fg - で一つ前のジョブに戻れます(cdと同じ!)。fg %1 と番号指定することで任意のものに戻れます。[1][2][3]と表示されているのがそれですね。ジョブ番号といいます。
元のジョブを続けたいけど入力は必要なくて待つだけ、というときにはbg (back ground) を使います。引数のルールはfgと同じ。これはコマンドを&つきで実行したときと同じ状態(バックグランド実行)になります。で、元のジョブを終了したいときはkill %1でOKです。
# makeはバックグランド実行したい [nt@localhost] $ bg [3]+ make -f large_program.mak & # tailはもう見ないので終了 [nt@localhost] $ kill %2 [2]+ Terminated: 15 tail -f php_error_log # viに戻る [nt@localhost] $ fg vim foo.rb
シェルプログラミング編
sh -n, sh -xでデバッグする
sh -n script.shとすると構文チェック、sh -x script.shとすると実行コマンドを標準エラーに出しながら実行。シェルスクリプトの開発時には便利です。
set -u, set -eで堅牢なスクリプトを書く
スクリプト内でset -uとすると、未定義の変数展開をエラーにしてくれます。set -eとすると、コマンドがエラーになった時点でスクリプトの実行を中断してくれます*1。
私に言わせれば、これを使っていないシェルスクリプトはuse strict; use warnings;していないperlプログラム、ErrorExceptionを使っていないphpプログラムのようなものです。使い捨てにするスクリプトならともかく、お金をもらって書くスクリプトには是非書きましょう。
{}でコマンドをグループ化する
echo "メッセージ" >> logfile.txt ls >> logfile.txt 別のコマンド >> logfile.txt
こんなスクリプトをときどき見ます。毎回ファイルを開いていてダサいですね。ファイル名の指定もDRYじゃありません。{}でグループ化しましょう。
{ echo "なにかメッセージ" ls 別のコマンド } >> logfile.txt
ちなみに、別記事で紹介されている&&、||の条件判断とグループ化を合わせるとこんな書き方ができます。
[ -f testfile.txt ] || { echo "file not found." exit 1 } grep word file.txt > tmp.txt && { tmp.txtを使った処理 : rm -f tmp.txt }
rubyのブロックみたいでちょっとかっこいいですね。ただしset -eしていると||が分岐しないでそこで終了しちゃいます。使い捨てのものに使ってひとりでドヤるにとどめておきましょう。
シェルスクリプトを捨てる
シェルスクリプトを書く上で大事なのが、シェルを使うのをやめる判断です。シェルは難しいことをやるのに向いていません。理由はたくさんありますが*2、スクリプトが大きくなるとそのうち保守が不可能になるので、技巧的だなーと思ったらさっさとシェルスクリプトを捨てて別のまともなプログラミング言語を使うことです。
代わりの言語はperlがいいでしょう。*nixならshの次に環境に入ってる確率が高くてモジュラーなプログラムが書けます*3。ちなみに、いくつかの商用UnixやLinuxで仕事してきましたが、入ってる率の高いスクリプト言語を感覚的に並べるとこんな感じになります。
sh,awk > perl >>> bash > python >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ruby
エディタの件
ついでにエディタの話を。
もしあなたが画家のようなプログラマーなら、生産性の高いものを使えばよいのです。しかしもし問題解決を旨とする職人ならば、悪いことは言わないのでviを使えるようにしておきましょう。例えるならemacsは画家のアトリエみたいなもんですが、viは鉛筆1本です。他人のemacsを使わせるのが拷問として知られる一方、訓練されたvi使いはどんな環境でも仕事ができます。sh, awkと同じでどこにでもあるからです。客先のサーバにemacsが入ってることなんてまずありません。
-
-
- -
-
追伸:
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
- 作者: ブルース・ブリン,Bruce Blinn,山下哲典
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2003/02
- メディア: 単行本
- 購入: 18人 クリック: 331回
- この商品を含むブログ (64件) を見る