如果我调用一个命令使用内核#系统在Ruby中,我如何得到它的输出?

system("ls")

当前回答

虽然使用反勾号或popen通常是您真正想要的,但它实际上并不能回答所提出的问题。可能有捕获系统输出的正当理由(可能是为了自动化测试)。我在谷歌上搜索了一下,找到了一个答案,我想把它贴在这里,以造福他人。

因为我需要这个来测试我的例子使用块设置来捕获标准输出,因为实际的系统调用隐藏在被测试的代码中:

require 'tempfile'

def capture_stdout
  stdout = $stdout.dup
  Tempfile.open 'stdout-redirect' do |temp|
    $stdout.reopen temp.path, 'w+'
    yield if block_given?
    $stdout.reopen stdout
    temp.read
  end
end

该方法使用tempfile存储实际数据来捕获给定块中的任何输出。使用示例:

captured_content = capture_stdout do
  system 'echo foo'
end
puts captured_content

您可以将系统调用替换为任何内部调用系统的东西。如果需要,还可以使用类似的方法来捕获stderr。

其他回答

将标准输出捕获到名为val的变量中最简单的解决方案:

val = capture(:stdout) do
  system("pwd")
end

puts val

缩短版本:

val = capture(:stdout) { system("ls") }

捕获方法由 active_support / core_ext /内核/ reporting.rb

类似地,我们也可以用:stderr捕获标准错误

我想扩展和澄清一下混沌的答案。

如果你用反勾号包围命令,那么你根本不需要(显式地)调用system()。反勾号执行命令并以字符串形式返回输出。然后你可以像这样把值赋给一个变量:

output = `ls`
p output

or

printf output # escapes newline chars

另一种方法是:

f = open("|ls")
foo = f.read()

注意,这是open中“ls”前面的“pipe”字符。这也可用于将数据送入程序的标准输入以及读取其标准输出。

你可以用反勾号:

`ls`

我发现下面是有用的,如果你需要返回值:

result = %x[ls]
puts result

我特别想列出我的机器上所有Java进程的pid,并使用以下方法:

ids = %x[ps ax | grep java | awk '{ print $1 }' | xargs]