94

Ruby からコマンド ライン コマンドを実行する方法はありますか? 「screen」、「rcsz」などのコマンドラインプログラムをダイヤルアウトして送受信する小さなRubyプログラムを作成しようとしています.

これらすべてを Ruby (MySQL バックエンドなど) と結び付けることができれば素晴らしいと思います。

4

5 に答える 5

217

はい。いくつかの方法があります:


a. %xまたは '`'を使用:

%x(echo hi) #=> "hi\n"
%x(echo hi >&2) #=> "" (prints 'hi' to stderr)

`echo hi` #=> "hi\n"
`echo hi >&2` #=> "" (prints 'hi' to stderr)

これらのメソッドは stdout を返し、stderr をプログラムのものにリダイレクトします。


b. 使用system:

system 'echo hi' #=> true (prints 'hi')
system 'echo hi >&2' #=> true (prints 'hi' to stderr)
system 'exit 1' #=> nil

このメソッドはtrue、コマンドが成功した場合に戻ります。すべての出力をプログラムにリダイレクトします。


c. 使用exec:

fork { exec 'sleep 60' } # you see a new process in top, "sleep", but no extra ruby process. 
exec 'echo hi' # prints 'hi'
# the code will never get here.

これにより、現在のプロセスがコマンドによって作成されたプロセスに置き換えられます。


d. (ルビー 1.9) 使用spawn:

spawn 'sleep 1; echo one' #=> 430
spawn 'echo two' #=> 431
sleep 2
# This program will print "two\none".

このメソッドは、プロセスが終了するのを待たず、PID を返します。


e. 使用IO.popen:

io = IO.popen 'cat', 'r+'
$stdout = io
puts 'hi'
$stdout = IO.new 0
p io.read(1)
io.close
# prints '"h"'.

このメソッドはIO、新しいプロセスの入出力を表すオブジェクトを返します。また、現在、プログラムに入力を与える唯一の方法です。


f. 使用Open3(1.9.2 以降)

require 'open3'

stdout,stderr,status = Open3.capture3(some_command)
STDERR.puts stderr
if status.successful?
  puts stdout
else
  STDERR.puts "OH NO!"
end

Open3には、2 つの出力ストリームへの明示的なアクセスを取得するための関数が他にもいくつかあります。popen に似ていますが、stderr にアクセスできます。

于 2010-07-01T17:03:18.273 に答える
14

Ruby でシステム コマンドを実行する方法はいくつかあります。

irb(main):003:0> `date /t` # surround with backticks
=> "Thu 07/01/2010 \n"
irb(main):004:0> system("date /t") # system command (returns true/false)
Thu 07/01/2010
=> true
irb(main):005:0> %x{date /t} # %x{} wrapper
=> "Thu 07/01/2010 \n"

しかし、コマンドの stdin/stdout を使用して実際に入力と出力を実行する必要がある場合は、IO::popen特にその機能を提供するメソッドを確認することをお勧めします。

于 2010-07-01T17:01:09.103 に答える
2

はい、これは確かに実行可能ですが、問題の「コマンド ライン」プログラムが「フル スクリーン」またはコマンド ライン モードで動作するかどうかによって、実装方法が異なります。コマンド ライン用に作成されたプログラムは、STDIN を読み取り、STDOUT に書き込む傾向があります。これらは、標準のバックティック メソッドや system/exec 呼び出しを使用して、Ruby 内で直接呼び出すことができます。

プログラムが screen や vi のような「フルスクリーン」モードで動作する場合、アプローチは異なる必要があります。このようなプログラムの場合、「expect」ライブラリの Ruby 実装を探す必要があります。これにより、画面に表示されると予想されるものと、それらの特定の文字列が画面に表示されたときに何を送信するかをスクリプト化できます。

これが最善のアプローチであるとは考えにくいため、既存のフルスクリーン アプリケーションを自動化するのではなく、何を達成しようとしているのかを調べて、それを行うための関連するライブラリ/gem を見つける必要があります。例として、「Ruby でのシリアル ポート通信に関する支援が必要」は、あなたが言及した特定のプログラムを使用して達成したい場合のダイヤルの前兆であるシリアル ポート通信を扱っています。

于 2010-07-01T17:06:30.487 に答える