推荐在 Ruby 中执行 shell 代码的方法
Open3.popen3 或 Open3.capture3:
Open3 实际上只使用 Ruby 的 spawn 命令,但为你提供了更好的 API。
Open3.popen3
Popen3 在子进程中运行并返回 stdin,stdout,stderr 和 wait_thr。
require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3("sleep 5s && ls")
puts "#{stdout.read} #{stderr.read} #{wait_thr.value.exitstatus}"
要么
require 'open3'
cmd = 'git push heroku master'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
puts "stdout is:" + stdout.read
puts "stderr is:" + stderr.read
end
将输出: stdout is:stderr is:fatal:不是 git 存储库(或任何父目录):。git
要么
require 'open3'
cmd = 'ping www.google.com'
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
while line = stdout.gets
puts line
end
end
将输出:
使用 32 个字节的数据 ping www.google.com [216.58.223.36]:
216.58.223.36 的回复:bytes = 32 time = 16ms TTL = 54
来自 216.58.223.36 的回复:bytes = 32 time = 10ms TTL = 54
来自 216.58 的回复 .223.36:bytes = 32 time = 21ms TTL = 54
来自 216.58.223.36 的回复:bytes = 32 time = 29ms TTL = 54
Ping 统计数据为 216.58.223.36:
数据包:已发送= 4,已接收= 4,已丢失= 0(0%损失),
以毫秒为单位的近似往返时间:
最小值= 10ms,最大值= 29ms,平均值= 19ms
Open3.capture3:
require 'open3'
stdout, stderr, status = Open3.capture3('my_funky_command', 'and', 'some', 'argumants')
if status.success?
# command completed successfully, do some more stuff
else
raise "An error occured"
end
要么
Open3.capture3('/some/binary with some args')
不推荐,但由于额外的开销和壳注入的可能性。
如果命令从 stdin 读取并且你想要为它提供一些数据:
Open3.capture3('my_funky_command', stdin_data: 'read from stdin')
使用 chdir 运行具有不同工作目录的命令:
Open3.capture3('my_funky_command', chdir: '/some/directory')