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

system("ls")

当前回答

请注意,所有向系统传递包含用户提供值的字符串的解决方案,%x[]等都是不安全的!不安全实际上意味着:用户可以触发代码在上下文中运行,并具有程序的所有权限。

据我所知,只有系统和Open3。popen3在Ruby 1.8中提供了一个安全/转义的变体。在Ruby 1.9中,IO::popen也接受数组。

只需将每个选项和参数作为数组传递给其中一个调用。

如果你不仅需要退出状态,还需要结果,你可能会使用Open3.popen3:

require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3('usermod', '-p', @options['shadow'], @options['username'])
stdout.gets(nil)
stdout.close
stderr.gets(nil)
stderr.close
exit_code = wait_thr.value

注意,块表单将自动关闭stdin, stdout和stderr-否则它们必须显式关闭。

更多信息:在Ruby中形成卫生shell命令或系统调用

其他回答

你可以用反勾号:

`ls`

您可以使用system()或%x[],这取决于您需要什么样的结果。

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

>> s = system 'uptime'
10:56  up 3 days, 23:10, 2 users, load averages: 0.17 0.17 0.14
=> true
>> s.class
=> TrueClass
>> $?.class
=> Process::Status

% x [. .]另一方面,将命令的结果保存为字符串:

>> result = %x[uptime]
=> "13:16  up 4 days,  1:30, 2 users, load averages: 0.39 0.29 0.23\n"
>> p result 
"13:16  up 4 days,  1:30, 2 users, load averages: 0.39 0.29 0.23\n"
>> result.class
=> String

Jay Fields的博客文章详细解释了system、exec和%x[..]]。

另一种方法是:

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

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

我在这里没有找到这个,所以添加它,我有一些问题得到完整的输出。

您可以重定向STDERR到STDOUT,如果您想捕获STDERR使用 撇号。 输出= ' grep hosts /private/etc/* 2>&1 '

来源:http://blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.html

如果你想使用Kernel#系统将输出重定向到一个文件,你可以这样修改描述符:

以追加模式将stdout和stderr重定向到文件(/tmp/log):

系统(ls状态”,:= > [/ tmp /日志,' '],:呃= > [/ tmp /日志,' '])

对于长时间运行的命令,这将实时存储输出。您还可以使用IO存储输出。管道和重定向它从内核#系统。