1. ホーム
  2. ruby

[解決済み] Ruby、execとsystemと%x()またはBackticksの違いについて

2022-03-23 04:23:03

質問

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

exec , system%x() または バックトラック

Rubyでプログラム的に端末のコマンドを実行するために使うのはわかるのですが、なぜ3種類の方法があるのか知りたいです。

どのように解決するのですか?

システム

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

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

呼び出されたプログラムは、現在の STDIN , STDOUTSTDERR オブジェクトを作成します。実際の戻り値は true , false または nil . この例では、日付は IO オブジェクトである STDIN . このメソッドは true がゼロステータスで終了した場合。 false は、プロセスがゼロ以外のステータスで終了した場合、そして nil は実行に失敗した場合

Ruby 2.6では exception: true を返す代わりに、例外を発生させます。 false または nil :

>> system('invalid')
=> nil

>> system('invalid', exception: true)
Traceback (most recent call last):
...
Errno::ENOENT (No such file or directory - invalid)

もう一つの副作用は、グローバル変数 $? が設定されます。 Process::Status オブジェクトを作成します。このオブジェクトは、呼び出されたプロセスのプロセス識別子(PID)や終了ステータスなど、呼び出し自体に関する情報を含みます。

>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>

バックトラック

バックトラック (``) はシステムプログラムを呼び出して、その出力を返します。最初の方法とは対照的に、コマンドは文字列で提供されるのではなく、バックチッ クのペアの中に入れることで提供されます。

>> `date`
=> Wed Sep 4 22:22:51 CEST 2013   

グローバル変数 $? もバックティックで設定されます。バックチックでは、文字列の補間も利用できます。

%x()

使用方法 %x は、バックチックスタイルの代わりとなるものです。これも出力を返します。その親戚のような %w%q (など)、ブラケット形式のデリミタが一致する限り、どのようなデリミタでも十分です。つまり %x(date) , %x{date}%x-date- はすべて同義語です。バックティックと同様に %x は、文字列の補間を利用することができます。

エグゼック

を使用することで Kernel#exec によって呼び出されたプロセスに置き換えられます。 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