Suppressing the Output of a Command Run Using 'System' Method While Running It in a Ruby Script

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

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

Ruby system command is giving me an output

If you don't care about the output, trash it:

system("sudo airodump-ng -w sidney wlan0 >/dev/null 2>&1")

I think the child process will inherit the parent's file descriptors.

Ruby suppress system true output

System returns true or false, depending on the success of the command.

Use %x to capture output:

pinger_pid = %x(ps | grep rake | awk '{print $1}')
puts pinger_pid
system 'kill', '-9', pinger_pid

Suppress Output in Rake Task db:schema:load

Here is a cleaner solution that works cross-system:

silence_stream(STDOUT) do
# anything written to STDOUT here will be silenced
Rake::Task["db:schema:load"].invoke
end

also

quietly do
# anything written to STDOUT or STDERR here will be silenced
Rake::Task["db:schema:load"].invoke
end

I prefer silence_stream(STDOUT) toquietly because it will still allow error messages written to STDERR to be shown, which will be helpful when the rake command starts to act up.

References: silence_stream, silence_warnings, & quietly

Suppress console output during RSpec tests

I suppress puts output in my classes by redirecting $stout to a text file. That way, if I need to see the output for any reason, it is there but it doesn't muddy up my test results.

#spec_helper.rb
RSpec.configure do |config|
config.before(:all, &:silence_output)
config.after(:all, &:enable_output)
end

public
# Redirects stderr and stout to /dev/null.txt
def silence_output
# Store the original stderr and stdout in order to restore them later
@original_stderr = $stderr
@original_stdout = $stdout

# Redirect stderr and stdout
$stderr = File.new(File.join(File.dirname(__FILE__), 'dev', 'null.txt'), 'w')
$stdout = File.new(File.join(File.dirname(__FILE__), 'dev', 'null.txt'), 'w')
end

# Replace stderr and stdout so anything else is output correctly
def enable_output
$stderr = @original_stderr
$stdout = @original_stdout
@original_stderr = nil
@original_stdout = nil
end

EDIT:

In response to the comment by @MyronMarston, it probably would be smarter to just insert the methods directly into before and after as blocks.

#spec_helper.rb
RSpec.configure do |config|
original_stderr = $stderr
original_stdout = $stdout
config.before(:all) do
# Redirect stderr and stdout
$stderr = File.new(File.join(File.dirname(__FILE__), 'dev', 'null.txt'), 'w')
$stdout = File.new(File.join(File.dirname(__FILE__), 'dev', 'null.txt'), 'w')
end
config.after(:all) do
$stderr = original_stderr
$stdout = original_stdout
end
end

It looks a little cleaner and keeps methods off of main.
Also, note that if you are using Ruby 2.0, you can use __dir__ instead of File.dirname(__FILE__).

EDIT2

Also it should be mentioned, that you can forward to true os /dev/null by using File::NULL as it was introduced in Ruby v 1.9.3. (jruby 1.7)

Then the code snippet will look as following:

#spec_helper.rb
RSpec.configure do |config|
original_stderr = $stderr
original_stdout = $stdout
config.before(:all) do
# Redirect stderr and stdout
$stderr = File.open(File::NULL, "w")
$stdout = File.open(File::NULL, "w")
end
config.after(:all) do
$stderr = original_stderr
$stdout = original_stdout
end
end

Ruby different results for %x{something} where something is quoted or unquoted

This is a peculiarity of Windows, not Ruby. What's going on is this:

Dir is not an executable but a native function of Windows/cmd.exe. (It's part of cmd.exe - so cmd.exe "traps" when you type dir and runs an internal function rather than looking for "dir.exe" or something out on your file path).

When you put something in quotes in cmd, it forces cmd.exe to look for that command on the path, not via it's internal functions.

You can test this by opening a command prompt in Windows and typing a built-in command (that doesn't exist in gnuwin32) such as copy:

>copy
The syntax of the command is incorrect.

>"copy"
'"copy"' is not recognized as an internal or external command,
operable program or batch file.

If you then create "copy.cmd" file with contents:

echo copy.cmd executed

when you run, you'll see:

>"copy"
copy.cmd executed

Make sense? Basically quoting the command you send to the shell (cmd.exe) from Ruby will cause a different interpretation by cmd.exe - it will prevent internal/built-in cmd.exe commands (such as dir and copy) from working, whereas external utils such as xcopy will work fine.

Run a shell script from ruby

You can do this a few different ways

Kernel.system "command"
%x[command]
`command`


Related Topics



Leave a reply



Submit