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

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

调用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 

如果你想利用可变forms的Kernel.system,它可以解决shell的许多引用问题,你可以使用Kernel.spawn接受的相同选项 。

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 

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

总是,问题是我看到的文本实际上来自stderr而不是stdout 。 因此,要将该文本纠缠到stdout中,请记住将2>&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

我也面临着这个问题……

请记住,使用ruby system调用时,您尝试使用的UNIX命令可能会提供“静默”选项 – 无需完全抑制终端输出!

例如:

 system 'curl -s "your_params_here"' 

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

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

如下:

  null_device = Gem.win_platform? ? "/nul" : "/dev/null" do method system "run command 1>#{null_device} 2>#{null_device} " p ($? == 0) end 

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

这应该工作

 system ls, STDOUT:'/dev/null'