以下のRubyメソッドの違いは何ですか?
exec
、system
および%x()
またはバッククォート
私はそれらがRubyを介してプログラム的に端末コマンドを実行するために使われていることを知っています、しかし私はこれをする3つの異なる方法がある理由を知りたいです。
システム
system
メソッドはシステムプログラムを呼び出します。このメソッドへの文字列引数としてコマンドを提供する必要があります。例えば:
>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true
呼び出されたプログラムは、あなたのRubyプログラムの現在のSTDIN
、STDOUT
およびSTDERR
オブジェクトを使用します。実際には、実際の戻り値はtrue
、false
またはnil
のいずれかです。この例では、日付はSTDIN
のIOオブジェクトを通して出力されました。このメソッドは、プロセスがゼロのステータスで終了した場合はtrue
、プロセスがゼロ以外のステータスで終了した場合はfalse
を返し、実行に失敗した場合はnil
を返します。
別の副作用は、グローバル変数$?
が Process::Status
オブジェクトに設定されることです。このオブジェクトには、呼び出されたプロセスのプロセス識別子(PID)や終了ステータスなど、呼び出し自体に関する情報が含まれています。
>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>
バッククォート
Backticks ( ``)はシステムプログラムを呼び出してその出力を返します。最初の方法とは対照的に、コマンドは文字列ではなく、バッククォートのペアの中に入れることで提供されます。
>> `date`
=> Wed Sep 4 22:22:51 CEST 2013
グローバル変数$?
もバッククォートを通して設定されます。バッククォートを使用すると、文字列補間を使用することもできます。
%x()
%x
を使用することは、バックティックスタイルに代わるものです。出力も返されます。その親戚%w
と%q
のように(他の人の間で)、大かっこスタイルの区切り文字が一致する限り、任意の区切り文字で十分です。これは%x(date)
、%x{date}
および%x-date-
がすべて同義語であることを意味します。バッククォートのように%x
は文字列補間を利用できます。
exec
Kernel#exec
現在のプロセス(あなたのRubyスクリプト)はexec
を通して呼び出されたプロセスに置き換えられます。メソッドは引数として文字列を取ることができます。この場合、文字列はシェル展開の対象になります。複数の引数を使用する場合、最初のものがプログラムの実行に使用され、次のものが呼び出されるプログラムへの引数として提供されます。
Open3.popen3
必要な情報が標準入力または標準エラーに書き込まれることがあり、それらを制御する必要がある場合もあります。ここで Open3.popen3
が役に立ちます。
require 'open3'
Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
pid = thread.pid
puts stdout.read.chomp
end
これは この答え に基づくフローチャートです。 端末をエミュレートするためにscript
を使用 も参照してください。
彼らは違うことをします。 exec
は、現在のプロセスを新しいプロセスに置き換えます。 決して戻ってこない。 system
は別のプロセスを呼び出します 終了値を返します 現在のプロセスへ。バッククォートを使用すると別のプロセスが呼び出され、 出力を返す そのプロセスの現在のプロセスへの.