Suppressing the output of a command run using 'system' method while running it in a ruby script

后端 未结 8 1219
醉梦人生
醉梦人生 2020-12-29 20:13

I am not sure if this makes sense but I am thinking if there is a way to suppress the output shown for a command when run using the system method in ruby? I mea

相关标签:
8条回答
  • 2020-12-29 20:43

    If you want to take advantage of the variadic form of Kernel.system, which side-steps the many quoting issues with shells, you can use the same options which Kernel.spawn accepts.

    TL;DR - Use :out => File::NULL to silence output from Kernel.system

    Arguments with special characters (spaces, etc.) can cause problems with the 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
    

    So if you are interpolating variables into a system call, it is safer to provide the arguments separately:

    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
    

    But now we have a problem if we want to hide the output.

    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
    

    We could close STDOUT using the :out => :close option:

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

    However, this might cause issues with certain commands which may try to attach to STDOUT.

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

    To fix this, we can go back to redirecting our output, using File::NULL to remain portable:

    irb(main):007:0> system "echo", "hi there", :out => File::NULL
    => true
    
    0 讨论(0)
  • 2020-12-29 20:46

    After a call to system the exit code is in the special variable $? so if useradd returns different values to indicate if the user was successfully added (e.g. 0 for success) then you can do the following:

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

    where the redirect to /dev/null will suppress the output.

    Alternatively if the program being called does not use its exit code to indicate success or failure you can use backticks and search for a particular substring in the output e.g.

    if `useradd xx`.include? 'success'
      puts 'it worked'
    else
      puts 'failed to add user'
    end
    
    0 讨论(0)
  • 2020-12-29 20:49

    IO.popen

    This is another good option:

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

    Nothing will get output to your stdout.

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

    0 讨论(0)
  • 2020-12-29 20:51

    You can also use backticks or %x

    0 讨论(0)
  • 2020-12-29 20:52

    This should work

    system ls, STDOUT:'/dev/null'
    
    0 讨论(0)
  • 2020-12-29 21:04

    I was faced with this question as well...

    Keep in mind that with ruby system calls, the UNIX command you are trying to use might offer a "silent" option--nullifying the need to suppress terminal output altogether!

    For instance:

    system 'curl -s "your_params_here"'
    

    Will suppress the output that typically accompanies a curl call.

    0 讨论(0)
提交回复
热议问题