2011年4月19日火曜日

システムコマンド実行時に'command not found'になる場合は、セミコロンで繋げとく(ruby編)

cf. PHPってこうやってBashスクリプトが書けるのですね・・・ | IDEA*IDEA

PHPに限らず、PerlもRubyもコード内にシェルコマンド実行ができますね。シェルもbashに限りません。

方法は、バッククォート括りです。
`command ...`
cf. コマンド出力 リテラル - Rubyリファレンスマニュアル

変数展開もできます。
var = 'value'
`command ... #{var}`

複数のコマンドを実行する場合は、単純に複数行で書きます。
`cmd1 ...`
`cmd2 ...`
`cmd3 ...`


ちなみに、以下は3プロセスを1つにまとめているので挙動は変わります。
`cmd1 ...; cmd2 ...; cmd3 ...`



さて本題ですが、以下のようにcdコマンドを書くとエラーになります。
$ cat cmd.rb
#!/usr/bin/env ruby

`cd /`

$ ./cmd.rb
./cmd.rb:4: command not found: cd /

原因は不明ですが、ひとまずコマンドの連続実行を表すセミコロンを末尾に付加しておくとエラーは出ないようです。
$ cat cmd.rb
#!/usr/bin/env ruby

`cd /;`

$ ./cmd.rb
→エラーなし

まあ、cdの場合は素直に'Dir::chdir'使えばいいのですが、組み込みメソッドでない場合などを考えると、末尾にセミコロンつけとく、というアドホックな解決もありかと思います。