如何从Ruby中调用shell命令

ruby shell interop


如何从Ruby程序内部调用shell命令?然后我如何从这些命令中获取输出回到Ruby中?




Answer 1 Steve Willard


该说明基于我的一个朋友的注释Ruby脚本。如果要改进脚本,请随时在链接上进行更新。

首先,请注意,当Ruby调用了一个外壳,它通常会调用 /bin/sh 的,不是猛砸。 /bin/sh 并非在所有系统上都支持某些Bash语法。

以下是执行shell脚本的方法。

cmd = "echo 'hi'" # Sample string that can be used
  1. Kernel#` ,通常称为反引号– `cmd`

    这和许多其他语言一样,包括Bash、PHP和Perl。

    返回shell命令的结果(即标准输出)。

    文件:http : //ruby-doc.org/core/Kernel.html#method-i-60

    value = `echo 'hi'`
    value = `#{cmd}`
  2. 内置语法 %x( cmd )

    x 字符是一个分隔符,它可以是任何字符。如果定界符是字符 ([{< )之一,则文字包含直到匹配的分隔符为止的字符,并考虑嵌套的定界符对。对于所有其他定界符,文字包含直到下次出现分隔符时,允许使用字符串插值 #{ ... }

    返回shell命令的结果(即标准输出),就像背标一样。

    文件:https://docs.ruby-lang.org/en/master/syntax/literals_rdoc.html#label-Percent+Strings

    value = %x( echo 'hi' )
    value = %x[ #{cmd} ]
  3. Kernel#system

    在子壳中执行给定的命令。

    如果找到命令并成功运行,则返回 true ,否则返回 false

    文件:http : //ruby-doc.org/core/Kernel.html#method-i-system

    wasGood = system( "echo 'hi'" )
    wasGood = system( cmd )
  4. Kernel#exec

    通过运行给定的外部命令替换当前进程。

    返回无,当前进程被替换,不再继续。

    文件:http : //ruby-doc.org/core/Kernel.html#method-i-exec

    exec( "echo 'hi'" )
    exec( cmd ) # Note: this will never be reached because of the line above

这里有一些额外的建议: $?$CHILD_STATUS 相同,如果使用反引号, system()%x{} ,则访问上次系统执行的命令的状态。然后,您可以访问 exitstatuspid 属性:

$?.exitstatus

更多阅读请看。




Answer 2 Ian


这是基于“ 何时使用在Ruby中启动子进程的每种方法 ”的流程图。另请参见“ 欺骗应用程序以使其标准输出是终端而不是管道 ”。

enter image description here




Answer 3 cynicalman


我喜欢这样做的方法是使用 %x 文字,它使得在命令中使用引号变得容易(并且易于阅读!),如下所示:

directorylist = %x[find . -name '*test.rb' | sort]

其中,在这种情况下,会将当前目录下的所有测试文件填充到文件列表中,你可以按照预期进行处理。

directorylist.each do |filename|
  filename.chomp!
  # work with file
end



Answer 4 Mihai A


这是我认为有关在Ruby中运行Shell脚本的最佳文章:“在Ruby 中运行Shell命令的6种方法 ”。

如果你只需要获得输出,请使用反标。

我需要更高级的东西,比如STDOUT和STDERR,所以我使用了Open4 gem。你有所有的方法在那里解释。




Answer 5 anshul


我最喜欢的是Open3

  require "open3"

  Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }