协慌网

登录 贡献 社区

从 Ruby 调用 shell 命令

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

答案

这个解释是基于我朋友的评论Ruby 脚本 。如果您想改进脚本,请随时在链接上更新它。

首先,请注意当 Ruby 调用 shell 时,它通常调用/bin/sh而不是 Bash。所有系统上/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 命令的结果,就像反引号一样。

    文档: http//www.ruby-doc.org/docs/ProgrammingRuby/html/language.html

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

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

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

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

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

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

    返回 none,当前进程被替换并且永远不会继续。

    文档: 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

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

$?.exitstatus

如需更多阅读,请参阅

这是基于此答案的流程图。另请参阅使用script模拟终端

在此输入图像描述

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

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

在这种情况下,将使用当前目录下的所有测试文件填充文件列表,您可以按预期处理该文件:

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