为了账号安全,请及时绑定邮箱和手机立即绑定

在Ruby中获取system()调用的输出

在Ruby中获取system()调用的输出

Smart猫小萌 2019-07-11 14:59:33
在Ruby中获取system()调用的输出如果我使用核#系统在Ruby中,我如何获得它的输出?system("ls")
查看完整描述

3 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

我想扩大和澄清混沌回答有点。

如果用backticks包围命令,那么根本不需要(显式)调用system()。backticks执行命令,并以字符串的形式返回输出。然后,可以将该值赋值给如下所示的变量:

output = `ls`p output

printf output # escapes newline chars


查看完整回答
反对 回复 2019-07-11
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

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

据我所知systemOpen3.popen3在Ruby1.8中确实提供了一个安全/转义变体。在Ruby1.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命令或系统调用


查看完整回答
反对 回复 2019-07-11
?
holdtom

TA贡献1805条经验 获得超10个赞

正确和安全地这样做的简单方法是使用Open3.capture2()Open3.capture2e(),或Open3.capture3().

用红宝石的后背和它的%x别名是在任何情况下都不安全如果与不受信任的数据一起使用。它是危险简单明了:

untrusted = "; date; echo"out = `echo #{untrusted}`                              
# BADuntrusted = '"; date; echo"'out = `echo "#{untrusted}"`                            
# BADuntrusted = "'; date; echo'"out = `echo '#{untrusted}'`                            
# BAD

这个system相反,函数正确地转义参数。如果使用正确:

ret = system "echo #{untrusted}"                      
 # BADret = system 'echo', untrusted                         
 # good

问题是,它返回退出代码而不是输出,而捕获输出则是复杂和混乱的。

到目前为止,这个线程中最好的答案提到了Open3,但没有提到最适合该任务的函数。Open3.capture2capture2ecapture3干得像system,但返回两个或三个参数:

out, err, st = Open3.capture3("echo #{untrusted}")     
# BADout, err, st = Open3.capture3('echo', untrusted)       
# goodout_err, st  = Open3.capture2e('echo', untrusted)      
# goodout, st      = Open3.capture2('echo', untrusted)      
 # goodp st.exitstatus

另一位提到IO.popen()..语法可能很笨拙,因为它需要一个数组作为输入,但它也能工作:

out = IO.popen(['echo', untrusted]).read              
 # good

为了方便起见,你可以把Open3.capture3()在一项职能中,例如:

## Returns stdout on success, false on failure, nil on error#def syscall(*cmd)
  begin
    stdout, stderr, status = Open3.capture3(*cmd)
    status.success? && stdout.slice!(0..-(1 + $/.size)) # strip trailing eol
  rescue
  endend

例子:

p system('foo')p syscall('foo')p system('which', 'foo')p syscall('which', 'foo')p system('which', 'which')p syscall('which', 'which')

产生以下结果:

nilnilfalsefalse/usr/bin/which         <— stdout from system('which', 'which')true               
    <- p system('which', 'which')"/usr/bin/which"       <- p syscall('which', 'which')


查看完整回答
反对 回复 2019-07-11
  • 3 回答
  • 0 关注
  • 1536 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信