如何从Ruby程序内部调用shell命令?然后如何将这些命令的输出返回到Ruby中?
当前回答
上面的答案已经非常棒了,但是我真的很想分享下面的总结文章:“在Ruby中运行Shell命令的6种方法”
基本上,它告诉我们:
# exec内核:
exec 'echo "hello $HOSTNAME"'
System和$?:
system 'false'
puts $?
Backticks ():
today = `date`
IO # execlp:
IO.popen("date") { |f| puts f.gets }
Open3#popen3—stdlib:
require "open3"
stdin, stdout, stderr = Open3.popen3('dc')
Open4#popen4—一个宝石:
require "open4"
pid, stdin, stdout, stderr = Open4::popen4 "false" # => [26327, #<IO:0x6dff24>, #<IO:0x6dfee8>, #<IO:0x6dfe84>]
其他回答
backticks(')方法是在Ruby中调用shell命令最简单的方法。它返回shell命令的结果:
url_request = 'http://google.com'
result_of_shell_command = `curl #{url_request}`
如果你真的需要Bash,请参考“最佳”答案中的注释。
首先,请注意,当Ruby调用shell时,它通常调用/bin/sh,而不是Bash。在所有系统上/bin/sh不支持某些Bash语法。
如果你需要使用Bash,在你想要的调用方法中插入Bash -c "your Bash-only command":
quick_output = system("ls -la")
quick_bash = system("bash -c 'ls -la'")
测试:
system("echo $SHELL")
system('bash -c "echo $SHELL"')
或者如果您正在运行一个现有的脚本文件,如
script_output = system("./my_script.sh")
Ruby应该尊重shebang,但你总是可以使用
system("bash ./my_script.sh")
为了确保这一点,尽管/bin/sh运行/bin/bash可能会有轻微的开销,但您可能不会注意到。
我最喜欢的是Open3
require "open3"
Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
在这些机制之间进行选择时需要考虑的一些事情是:
你只是想要stdout还是 也需要stderr ?甚至 分离出来吗? 你的产出有多大?你想要 将整个结果保存在内存中? 你想读一些你的吗 在子进程静止时输出 跑步吗? 你需要结果代码吗? 你需要一个Ruby对象吗 表示流程并允许您 按需杀死它?
您可能需要简单的反撇号(' ')、system()和IO。popen到成熟的Kernel.fork/Kernel。执行IO。pipe和IO.select。
如果子进程执行时间过长,您可能还想在混合过程中加入超时。
不幸的是,这在很大程度上取决于情况。
在我看来,这是关于在Ruby中运行shell脚本的最好的文章:“在Ruby中运行shell命令的6种方法”。
如果您只需要获得输出,请使用反勾号。
我需要更高级的东西,比如STDOUT和STDERR,所以我使用了Open4 gem。这里已经解释了所有的方法。
推荐文章
- 是否可以在MiniTest中运行单个测试?
- 如何在Ruby中生成a和b之间的随机数?
- 查看PS命令的全部输出
- 确保一次只运行一个shell脚本实例的快速方法
- 无法安装gem -未能建立gem本地扩展-无法加载这样的文件——mkmf (LoadError)
- 如何在Ruby中创建文件
- 什么是Ruby文件。开放模式和选项?
- Ruby数组到字符串的转换
- 如何分割(块)一个Ruby数组成X元素的部分?
- Ruby中“or”和||的区别?
- Git与Mercurial仓库的互操作性
- 如何测试参数是否存在在轨道
- 如何在Makefile中设置子进程的环境变量
- 如何让“wc -l”打印没有文件名的行数?
- 有效地测试Linux上的端口是否打开?