在ruby脚本中运行命令时,使用'system'方法抑制运行命令的输出

时间:2009-12-25 09:06:19

标签: ruby

我不确定这是否有意义,但我在想是否有办法在ruby中使用system方法运行时抑制为命令显示的输出?我的意思是它应该只向STDOUT输出true或false,而不是输出命令。我认为只有在命令可以静默运行而不是system方法运行时才能完成。有人可以提供更多的见解吗?

8 个答案:

答案 0 :(得分:41)

如果你想利用可变形式的Kernel.system,它可以解决shell的许多引用问题,你可以使用相同的options which Kernel.spawn accepts

TL; DR - 使用:out => File::NULL使Kernel.system的输出静音

带有特殊字符(空格等)的参数可能会导致shell出现问题:

irb(main):001:0> filename_with_spaces = "foo bar.txt"
=> "foo bar.txt"

irb(main):002:0> system "ls -l #{filename_with_spaces}"
ls: bar.txt: No such file or directory
ls: foo: No such file or directory
=> false

因此,如果要将变量插入到系统调用中,则单独提供参数会更安全:

irb(main):003:0> system "ls", "-l", filename_with_spaces
-rw-r--r--  1 nobody  nobody  9 Feb  1 16:53 foo bar.txt
=> true

但是现在我们想要隐藏输出时会遇到问题。

irb(main):004:0> system "ls", "-l", filename_with_spaces, "> /dev/null"
ls: > /dev/null: No such file or directory
-rw-r--r--  1 nobody  nobody  9 Feb  1 16:53 foo bar.txt
=> false

我们可以使用:out => :close选项关闭STDOUT:

irb(main):005:0> system "ls", "-l", filename_with_spaces, :out => :close
=> true

但是,这可能会导致某些可能尝试附加到STDOUT的命令出现问题。

irb(main):006:0> system "echo", "hi there", :out => :close
echo: write: Bad file descriptor
=> false

要解决此问题,我们可以返回重定向输出,使用File::NULL保持可移植性:

irb(main):007:0> system "echo", "hi there", :out => File::NULL
=> true

答案 1 :(得分:23)

在调用system之后,退出代码位于特殊变量$?中,因此如果useradd返回不同的值以指示用户是否已成功添加(例如0表示成功),则你可以做到以下几点:

system('useradd xx > /dev/null')
if $? == 0
  puts 'added'
else
  puts 'failed'
end

重定向到/dev/null会抑制输出。

或者,如果被调用的程序不使用其退出代码来表示成功或失败,则可以使用反引号并在输出中搜索特定的子字符串,例如

if `useradd xx`.include? 'success'
  puts 'it worked'
else
  puts 'failed to add user'
end

答案 2 :(得分:7)

作为一个附录,当我使用反引号并且从命令行运行脚本时看到输出“滑过”我的变量时,我几次感到惊讶。

问题始终存在,我看到的文字实际上来自stderr而不是stdout。因此,要将该文本纠缠到stdout中,请记住将2>&1附加到您尝试运行的命令中。

我希望这对某人有帮助。我只是浪费了二十分钟重新学习这一课:)

答案 3 :(得分:1)

<强> IO.popen

这是另一个不错的选择:

IO.popen(['echo', 'a']) do |f|
  f.read == "a\n" or raise
end
$?.exitstatus == 0 or raise

什么都不会输出到你的标准输出。

http://www.ruby-doc.org/core-2.1.4/IO.html#method-c-popen

答案 4 :(得分:1)

我也面临这个问题......

请记住,对于ruby system调用,您尝试使用的UNIX命令可能会提供&#34; silent&#34;选项 - 无需完全抑制终端输出!

例如:

system 'curl -s "your_params_here"'

将抑制通常伴随卷曲调用的输出。

答案 5 :(得分:0)

  • 定义null_device,它的操作系统dependent windows 7和更新的nul,而 * nix 系统使用/dev/null
  • 运行命令
  • 将其标准和错误输出重定向到null_device
  • 然后使用退出代码或@mikej的反引号方法mentioned来确定输出

如下:

 null_device = Gem.win_platform? ? "/nul" : "/dev/null"

 do method
   system "run command 1>#{null_device} 2>#{null_device} "
   p ($? == 0)
 end

答案 6 :(得分:-2)

您也可以使用反引号或%x

答案 7 :(得分:-2)

这应该有效

system ls, STDOUT:'/dev/null'