web-dev-qa-db-ja.com

Ruby、exec、systemと%x()またBackticksの違い

以下のRubyメソッドの違いは何ですか?

execsystemおよび%x()またはバッククォート

私はそれらがRubyを介してプログラム的に端末コマンドを実行するために使われていることを知っています、しかし私はこれをする3つの異なる方法がある理由を知りたいです。

341
Mr. Black

システム

system メソッドはシステムプログラムを呼び出します。このメソッドへの文字列引数としてコマンドを提供する必要があります。例えば:

>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true

呼び出されたプログラムは、あなたのRubyプログラムの現在のSTDINSTDOUTおよびSTDERRオブジェクトを使用します。実際には、実際の戻り値はtruefalseまたは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
378
Konrad Reiche

これは この答え に基づくフローチャートです。 端末をエミュレートするためにscriptを使用 も参照してください。

enter image description here

222
Ian

彼らは違うことをします。 execは、現在のプロセスを新しいプロセスに置き換えます。 決して戻ってこないsystemは別のプロセスを呼び出します 終了値を返します 現在のプロセスへ。バッククォートを使用すると別のプロセスが呼び出され、 出力を返す そのプロセスの現在のプロセスへの.

100
William Pursell