2010-07-01 169 views
76

有沒有辦法通過Ruby運行命令行命令?我正在嘗試創建一個小型的Ruby程序,它可以通過命令行程序(如「屏幕」,「rcsz」等)撥出和接收/發送。在Ruby腳本中運行命令行命令

如果我能將所有這些與Ruby(MySQL後端等)

回答

13

有幾種方法可以在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" 

但是如果你需要真正用命令的標準輸入/輸出進行輸入和輸出,你可能會想看看IO::popen方法,具體提供了便利。

+0

POPEN效果很好,如果你的應用程序只是有標準的。如果你需要更多的互動還是想做一些與標準輸出不同,標準輸入和標準錯誤尤其你也想看看open3:http://ruby-doc.org/core/classes/Open3.html – 2010-07-02 01:26:35

180

是的。有幾種方法:


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對象reperesents的新工藝的輸入/輸出。這也是目前我知道給節目輸入的唯一方法。


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有得到兩個輸出流顯式訪問等多種功能。它類似於popen,但可以讓你訪問stderr。

+0

精闢概括阿德里安, 感謝您分享這些信息。 – KomodoDave 2012-12-12 12:30:42

+0

獎金把戲:'io = IO.popen'cat> out.log','r +'';將命令的輸出寫入「out.log」 – Narfanator 2013-06-03 04:49:35

+1

每個人的贊成和反對意見是什麼。我如何決定使用哪一個?如何使用'FileUtils' [http://ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html]? – Ava 2013-08-15 20:13:37

2

是這當然是可行的,但實現的方法的不同依賴於所討論的「命令行」的節目是否在「全屏」或命令行模式操作。爲命令行編寫的程序傾向於讀取STDIN並寫入STDOUT。這些可以使用標準反引號方法和/或system/exec調用直接在Ruby中調用。

如果程序中,如屏幕或vi「全屏」模式下運行,則方法有不同。對於像這樣的程序,您應該查找「期望」庫的Ruby實現。這將允許您編寫您希望在屏幕上看到的內容以及在屏幕上顯示特定字符​​串時要發送的內容。

這不太可能是最好的方法,你應該看看你想要實現的目標,並找到相關的庫/ gem來做到這一點,而不是試圖自動化現有的全屏應用程序。作爲一個例子與串口通信「Need assistance with serial port communications in Ruby」交易,預光標撥號如果這是你想用你提到的具體方案來實現的。

+0

的簡化版本Expect是Ruby中可用使用其內置的[控股](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/pty/rdoc/PTY.html)模塊。 – 2013-01-07 23:06:03

6
folder = "/" 
list_all_files = "ls -al #{folder}" 
output = `#{list_all_files}` 
puts output 
0

最常用的方法是使用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