How to Run System Commands From Ruby

Rubyから外部コマンドを実行したい場合…

…例えばHTMLファイルをPDFに変換するwkhtmltopdfなど。

使用できるRubyメソッドは幾つかあります。

これらのメソッドを一緒に探ってみましょう!

Rubyシステムメソッド

Rubyシステムメソッドは、外部コマンドを実行する最も簡単な方法です。

次のようになります。

また、コマンドの実行が完了するまで Ruby プログラムを待たせます。

  • true コマンドが動作した場合
  • false コマンドがエラーコードを返した場合
  • nil コマンド実行に失敗(コマンドが見つからない)場合

グローバル変数 $? で最後に実行した外部コマンドの終了ステータスコードを取得することが可能です。 このステータスコードから、なぜコマンドが失敗したのか、より詳しい情報を得ることができます。

シェル拡張とは

外部コマンドをsystemで実行すると、「シェル拡張」効果が得られます。

シェル拡張とはシェル (sh/bash/zsh) がいくつかの特殊文字(*, ?, ")# "best"

This will not change the current environment of your Ruby application.

%x / Kernel#`

If you want to get the output from the command you're running, instead of displaying it then you can use %xまたは Kernel#`メソッドを取ることです。

これらは同じことをします。

`ls`

以下に例を示します。%xを使った別の例:

%x|ls|

これら二つの例は ls コマンドの出力を文字列で返します。

注意すべきは、スレッドの中で実行しなければ、コマンドが終了するまでまだ待たされることです。

How to Use Fork + Exec To Run External Commands on a Separate Process

フォークは現在のプロセス (Ruby アプリ) のコピーを作成し、そのコピーを exec を使用して別のプロセスに置き換えることができます。

これは Unix の世界でよく使われるパターンです。

これがどのように動作するか説明します。

fork { exec("ls") }

これは別のプロセスで ls を実行し & その出力を表示します。

重要:

forkなしでexecを使用すると、現在のプロセスを置き換えることになります。

これは、Rubyプログラムが終了することを意味します。

How to Use the Popen Method For Two Way Communication With An External Program

もし必要なら:

  • More control over the process
  • Two two-way communication

そして IO.popen method is what you looking at the following to.

次の例では、popen メソッドを使って irb プロセスを起動し、& 入力を送り、出力を読みます。

r = IO.popen("irb", "r+")r.write "puts 123 + 1\n"3.times { puts r.gets }r.write "exit\n"

この r 変数は IO オブジェクトで、これは通常のファイルのように & 書いたり読んだりできることを意味しています。

また、popenを使用すると、外部コマンドは独自のプロセスで実行されるので、スレッドで実行する必要はありません。

また、標準ライブラリにpopen3メソッドがあります。

通常の popen との違いは、通常の出力 & エラー メッセージを別の IO オブジェクトに分割する点です。

まとめ

Rubyで外部コマンドと対話できるさまざまな方法について学びました。

これらには注意してください!

Rubyアプリにセキュリティ問題を起こしたくなければ、これらのコマンドに何らかのユーザー入力を渡さないようにしてください。

コメントを残す

メールアドレスが公開されることはありません。