如何从Ruby程序内部调用shell命令?然后如何将这些命令的输出返回到Ruby中?
当前回答
我们可以通过多种方式来实现它。
使用Kernel#exec命令执行后什么都没有:
exec('ls ~')
使用反引号或%x
`ls ~`
=> "Applications\nDesktop\nDocuments"
%x(ls ~)
=> "Applications\nDesktop\nDocuments"
使用Kernel#system命令,如果成功返回true,不成功返回false,如果命令执行失败返回nil:
system('ls ~')
=> true
其他回答
你也可以使用反勾操作符('),类似于Perl:
directoryListing = `ls /`
puts directoryListing # prints the contents of the root directory
如果你需要简单的东西,很方便。
你想要使用哪种方法取决于你想要完成什么;有关不同方法的更多细节,请查看文档。
我最喜欢的是Open3
require "open3"
Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
上面的答案已经非常棒了,但是我真的很想分享下面的总结文章:“在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>]
您可以使用如下格式方法打印一些信息:
puts format('%s', `ps`)
puts format('%d MB', (`ps -o rss= -p #{Process.pid}`.to_i / 1024))
如果你真的需要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可能会有轻微的开销,但您可能不会注意到。
推荐文章
- 我如何让红宝石打印一个完整的回溯而不是截断一个?
- 删除Bash脚本中的重复条目
- 如何将Bash命令的输出分配给变量?
- 如何使用RSpec的should_raise与任何类型的异常?
- PHP中的异步shell执行器
- 如何创建退出消息
- 忽略GEM,因为没有构建它的扩展
- 在Gem::Specification.reset期间未解决的规格:
- Git显示“警告:永久添加到已知主机列表”
- Delete_all vs destroy_all
- 双引号vs单引号
- 用any可以吗?'来检查数组是否为空?
- Rails获取“each”循环的索引
- 检索Linux上单个进程的CPU使用情况和内存使用情况?
- 如何从远程SSH会话发送数据到本地剪贴板