2010-11-04

Ruby 驅動外部程式的方法: %x, exec, system, IO.popen

以下外部程式名稱以「external_cmd」為範例
Linux 前景執行外部程式指令:
# external_cmd
或以背景執行外部程式:
# external_cmd &

1. %x 是最普遍的方法,用在想要取得外部程式的標準輸出結果,但該外部程式不需要標準輸入時。另外,無論是否以背景執行該外部程式,呼叫 %x 的 ruby 程式皆會等待外部程式結束,才會繼續執行。
Ruby 範例程式碼如下,執行外部程式的輸出會儲存在 external_cmd_output 變數內。注意{}裡面並不需要再用雙引號來框住指令。另外,%x 方法和 `` 語法相同。
external_cmd_output = %x{external_cmd}
external_cmd_output = %x{external_cmd &}
external_cmd_output = `external_cmd`
external_cmd_output = `external_cmd &`


2. exec 方法會在執行外部程式完畢以後,終止呼叫 exec 的 ruby 程式,不傳回任何值。
Ruby 範例程式碼如下。
exec "external_cmd"
puts "never get here." # 這一行的 ruby 程式不會被執行


3. system 方法會在執行外部程式完畢以後,傳回執行的結果,成功則傳回 true,失敗則傳回 false。system 和 %x 方法的不同之處,除了傳回值不一樣,我認為使用的時機最大的不同點在於執行背景程式的時刻。以 %x 背景執行外部程式時,會等待該外部程式結束後,再執行下一行 ruby 程式;然而以 system 背景執行外部程式時,在傳回執行結果後,無須等待外部程式結束即執行下一行 ruby 程式。
Ruby 範例程式碼如下,執行外部程式的結果(成功與否)會儲存在 external_cmd_result 變數內。
external_cmd_result = system "external_cmd"
external_cmd_result = system "external_cmd &"


4. IO.popen 方法適用於外部程式需要標準輸入的時候,如互動式的外部程式。若 IO.popen 執行的外部程式需要標準輸入時,在標準輸入串流被關閉後才會開始執行。
Ruby 範例程式碼如下,其中「text of output」這段文字會被輸入到 external_cmd 的標準輸入,另外 external_cmd 的標準輸出會被 puts 印出。
IO.popen( "external_cmd", 'r+' ) do |pipe|
    pipe.puts "text of output"
    pipe.close_write
    puts pipe.read
end

沒有留言: