如何调用 shell 命令从 Ruby 程序内?如何做,然后得到输出这些命令从拼音到吗?

2008-08-05 12:56:52
问题评论:

回答:

本说明根据此注释的 Ruby 脚本从我的一个朋友。如果您想要提高脚本,随意链接处对其进行更新。

首先,请注意当 Ruby 调用 shell,则它通常调用/bin/sh大扫除。/bin/sh在所有系统上不支持一些 Bash 语法。

执行一个 shell 脚本的方法

cmd = "echo 'hi'" # Sample string that can be used

1.Kernel#`,通常称为 backticks – `cmd`

这就像许多其他语言,包括大扫除、 PHP 和 Perl

返回的结果的 shell 命令。

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

value = `echo 'hi'`
value = `#{cmd}`

2.内置语法, %x( cmd )

x字符后面的字符是分隔符,可以是任何字符。如果分隔符是字符之一([{<包含的字符最多匹配的结束分隔符中,考虑对嵌套的分隔符的文本。所有其他分隔符,文本包含的字符最多分隔符字符的下一个匹配项。允许字符串插值#{ ... }

返回的 shell 命令,就像 backticks 一样的结果。

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

value = %x( echo 'hi' )
value = %x[ #{cmd} ]

3。 Kernel#system

在 subshell 中,执行给定的命令

返回︰ 如果命令找,否则运行成功,则返回 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

额外的建议

$?如果您使用 backticks、 system()%x{}$CHILD_STATUS,相同访问最后一个执行的系统命令的状态。然后,您可以访问exitstatuspid属性

$?.exitstatus

更多阅读

我需要记录我在生产服务器上的可执行文件的输出,但是发现没有办法。我使用#{cmd}的认购和 logger.info (#{cmd})。有没有任何方法来记录其输出对生产?

IO#popen() 和 Open3#popen3()。...mentalized.net/journal/2010/03/08/

出于完整性的考虑 (如第一次,我认为这也是一个 Ruby 的命令)︰ Rake具有sh它不会"运行系统命令cmd如果多个参数给出了该命令不会运行与外壳 (相同的语义 Kernel::exec 和 Kernel::system)"。

默认情况下,Backticks 不捕获 STDERR。追加 2 > & 1 如果您想要捕获的命令

我认为该答案会略微改善是否它说 backticks 和 %x 返回"输出",而不是"结果",给定的命令。后者可能被误认为退出状态。还是只有我是?

我喜欢这样做的方法使用%x,这使它很容易 (和可读 !) 若要在命令中使用引号,如下所示︰

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

其中,在这种情况下,将使用填充文件列表如预期的那样可以处理当前目录下的所有测试文件︰

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

问题是关于大扫除,并看不到在什么意义上一个可以考虑该注释相关的问题的回答。问题不是关于获取的已排序的目录列表。

那样%x[ cmd ]将数组返回给您吗?

上述不适合我。< 主 >︰ 未定义的方法each' for :String (NoMethodError)以前的工作原理为您?我使用ruby -v ruby 1.9.3p484 (2013-11-22 revision 43786) [i686-linux]确实从命令返回一个数组,以便循环将实际工作?

在我看来,有关在 Ruby 中运行 shell 脚本还有最佳文章︰"6 在 Ruby 中运行外壳命令方式".

如果您只需要获取输出使用 backticks。

我需要标准输出和 STDERR 等更高级的东西,所以我使用了 Open4 的 gem。必须存在所述的所有方法。

该链接将断开。等效tech.natemurray.com/2007/03/ruby-shell-commands.html

是的我会更新公告。谢谢。

此处所述的公告不讨论%x语法选项。

Open4 的 + 1。我已经开始尝试实现其spawn方法我自己版本,当我发现这。

@MihaiA-我有一个小问题 ssh 连接状态。请帮助我- stackoverflow.com/questions/28799593/... ,谢谢。

我的收藏夹是Open3

  require "open3"

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

我也喜欢 open3,尤其是 Open3.capture3: ruby-doc.org/stdlib-1.9.3/libdoc/open3/rdoc/... -> stdout, stderr, status = Open3.capture3('nroff -man', :stdin_data => stdin)

这些机制之间进行选择时考虑的因素包括︰

  1. 不要只需要标准输出或是否需要以及 stderr?或甚至分离出?
  2. 您的输出有多大?您想要保存在内存中的整个结果吗?
  3. 子进程仍在运行时读取某些输出吗?
  4. 您需要结果代码吗?
  5. 您需要一个 ruby 的对象,它表示该进程,并允许您按需终止它吗?

您可能需要从简单的 backticks (`), system(), andIO.popento full-blownKernel.fork Kernel.execwithIO.pipeandIO.select 的/

此外可以组合成引发超时,如果子花很长时间来执行。

遗憾的是,它取决于很多.

内容来源于Stack Overflow Calling shell commands from Ruby
请输入您的翻译

Calling shell commands from Ruby

确认取消