system の挙動
Rubyの組み込み関数であるsystemは、引数の数によって異なる挙動をするようです。今日はそいつではまってしまいました。
例えば、下記のソースファイルから作られた tmp.exe という実行ファイルがあったとします。起動時に与えられたパラメータを出力するだけのプログラムです。
# tmp.exe のソースファイル tmp.cpp #include <cstdio> int main(int argc, char *argv[]) { for (int i = 0; i < argc; ++i) { printf("argv[%d] = \"%s\", ", i, argv[i]); } printf("\n") return 0; }
このtmp.exeを、下記の2種類のRubyスクリプトから呼び出してみます。
# <test_A.rb> paramA="tmp.exe -f -d" system(paramA)
# <test_B.rb> paramB_a="tmp.exe" paramB_b="-f -d" system(paramB_a, paramB_b)
一見、行っていることはまったく同じように見えるのですが、出力は次のような結果になります。
$ ./test_A.rb argv[0] = "tmp.exe", argv[1] = "-f", argv[2] = "-d" $ ./test_B.rb argv[1] = "tmp.exe", argv[1] = "-f -d"
びっくりですね。
system関数にパラメータなどをまとめた一つの文字列として渡すと、各パラメータがパースされてtmp.exeに渡されていますが、パラメータを分けて渡すとパースされない状態でtmp.exeに渡されています。
先輩プログラマから教えてもらったのですが、Rubyのsystem関数は、引数が1つのときは、それをシェルを介して実行し、引数が複数のときはプロセス生成のAPIに直接渡すそうです。
伝聞でしかないので、このあたりは使用をしっかり調べておこうと思います。いろいろなことがうろ覚えで、「なんとなく」で書いたコードでも動いてしまうという便利すぎるRubyですが、このあたりの細かいところについても知っておかないと、今日のように思わぬ落とし穴にはまってしまいそうで少し怖いです。今までは「たのしいRuby」だけでやってきたのですが、「プログラミングRuby」あたりも買っておこう。
- 作者: Dave Thomas,Chad Fowler,Andy Hunt,まつもとゆきひろ,田和勝
- 出版社/メーカー: オーム社
- 発売日: 2006/08/26
- メディア: 大型本
- 購入: 7人 クリック: 270回
- この商品を含むブログ (152件) を見る
- 作者: Dave Thomas,Chad Fowler,Andy Hunt,まつもとゆきひろ,田和勝
- 出版社/メーカー: オーム社
- 発売日: 2006/08/26
- メディア: 大型本
- 購入: 3人 クリック: 67回
- この商品を含むブログ (72件) を見る
たのしいRuby 第2版 Rubyではじめる気軽なプログラミング
- 作者: 高橋征義,後藤裕蔵
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/08/05
- メディア: 単行本
- 購入: 11人 クリック: 350回
- この商品を含むブログ (259件) を見る