มีวิธีเรียกใช้คำสั่งบรรทัดคำสั่งผ่าน Ruby หรือไม่? ฉันกำลังพยายามสร้างโปรแกรม Ruby เล็ก ๆ ที่สามารถโทรออกและรับ / ส่งผ่านโปรแกรมบรรทัดคำสั่งเช่น 'screen', 'rcsz' เป็นต้น
จะดีมากถ้าฉันสามารถผูกทั้งหมดนี้เข้ากับ Ruby (แบ็กเอนด์ MySQL ฯลฯ )
มีวิธีเรียกใช้คำสั่งบรรทัดคำสั่งผ่าน Ruby หรือไม่? ฉันกำลังพยายามสร้างโปรแกรม Ruby เล็ก ๆ ที่สามารถโทรออกและรับ / ส่งผ่านโปรแกรมบรรทัดคำสั่งเช่น 'screen', 'rcsz' เป็นต้น
จะดีมากถ้าฉันสามารถผูกทั้งหมดนี้เข้ากับ Ruby (แบ็กเอนด์ MySQL ฯลฯ )
คำตอบ:
ใช่. มีหลายวิธี:
ก. ใช้%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 ไปยังโปรแกรม
ข. ใช้system
:
system 'echo hi' #=> true (prints 'hi')
system 'echo hi >&2' #=> true (prints 'hi' to stderr)
system 'exit 1' #=> nil
วิธีนี้จะส่งคืนtrue
หากคำสั่งสำเร็จ มันเปลี่ยนเส้นทางผลลัพธ์ทั้งหมดไปยังโปรแกรม
ค. ใช้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.
ซึ่งจะแทนที่กระบวนการปัจจุบันด้วยกระบวนการที่สร้างขึ้นโดยคำสั่ง
ง. (ทับทิม 1.9) ใช้spawn
:
spawn 'sleep 1; echo one' #=> 430
spawn 'echo two' #=> 431
sleep 2
# This program will print "two\none".
วิธีนี้ไม่รอให้กระบวนการออกและส่งคืน PID
จ. ใช้IO.popen
:
io = IO.popen 'cat', 'r+'
$stdout = io
puts 'hi'
$stdout = IO.new 0
p io.read(1)
io.close
# prints '"h"'.
วิธีนี้จะส่งคืนIO
วัตถุที่แสดงอินพุต / เอาต์พุตของกระบวนการใหม่ซ้ำ ขณะนี้ยังเป็นวิธีเดียวที่ฉันรู้ในการป้อนข้อมูลโปรแกรม
ฉ. ใช้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
io = IO.popen 'cat > out.log', 'r+'
; เขียนผลลัพธ์ของคำสั่งเป็น "out.log"
FileUtils
[ ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html] ?
มีสองสามวิธีในการเรียกใช้คำสั่งระบบใน 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
วิธีการซึ่งนำเสนอสิ่งอำนวยความสะดวกนั้นโดยเฉพาะ
folder = "/"
list_all_files = "ls -al #{folder}"
output = `#{list_all_files}`
puts output
ใช่สิ่งนี้ทำได้อย่างแน่นอน แต่วิธีการใช้งานจะแตกต่างกันไปขึ้นอยู่กับว่าโปรแกรม "บรรทัดคำสั่ง" ที่เป็นปัญหาทำงานในโหมด "เต็มหน้าจอ" หรือโหมดบรรทัดคำสั่ง โปรแกรมที่เขียนสำหรับบรรทัดคำสั่งมักจะอ่าน STDIN และเขียนถึง STDOUT สิ่งเหล่านี้สามารถเรียกได้โดยตรงภายใน Ruby โดยใช้เมธอด backticks มาตรฐานและ / หรือการเรียกระบบ / exec
หากโปรแกรมทำงานในโหมด "เต็มหน้าจอ" เช่นหน้าจอหรือ vi วิธีการนั้นจะต้องแตกต่างออกไป สำหรับโปรแกรมเช่นนี้คุณควรมองหาการใช้งาน Ruby ของไลบรารี "คาดหวัง" สิ่งนี้จะช่วยให้คุณสามารถเขียนสคริปต์สิ่งที่คุณคาดว่าจะเห็นบนหน้าจอและสิ่งที่จะส่งเมื่อคุณเห็นสตริงเหล่านั้นปรากฏบนหน้าจอ
นี่ไม่น่าจะเป็นแนวทางที่ดีที่สุดและคุณน่าจะดูสิ่งที่คุณพยายามจะบรรลุและค้นหาไลบรารี / อัญมณีที่เกี่ยวข้องเพื่อทำสิ่งนั้นแทนที่จะพยายามทำให้แอปพลิเคชันเต็มหน้าจอที่มีอยู่เป็นไปโดยอัตโนมัติ ดังตัวอย่าง " ต้องการความช่วยเหลือเกี่ยวกับการสื่อสารพอร์ตอนุกรมใน Ruby " ที่เกี่ยวข้องกับการสื่อสาร Serial Port ซึ่งเป็นเคอร์เซอร์ล่วงหน้าเพื่อโทรออกหากนั่นคือสิ่งที่คุณต้องการบรรลุโดยใช้โปรแกรมเฉพาะที่คุณกล่าวถึง
วิธีที่ใช้บ่อยที่สุดคือการใช้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