web-dev-qa-db-ja.com

Rubyスクリプト内でコマンドラインコマンドを実行する

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

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

89
geetfun

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


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。(Ruby 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にアクセスできます。

203
Adrian

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 メソッド、特にその機能を提供します。

14
Mark Rushakoff
 folder = "/"
 list_all_files = "ls -al #{folder}"
 output = `#{list_all_files}`
 puts output
7
ohho

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

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

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

2
Steve Weet

最も使用される方法はOpen3を使用することです。ここに、いくつかの修正を加えた上記のコードを編集したバージョンを示します。

require 'open3'
puts"Enter the command for execution"
some_command=gets
stdout,stderr,status = Open3.capture3(some_command)
STDERR.puts stderr
if status.success?
  puts stdout
else
  STDERR.puts "ERRRR"
end
0