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
What's the Best Way to Talk to a Database While Using Sinatra
Is There a Literal Notation for an Array of Symbols
Access Instance Variable from Outside the Class
Convert an Array of Integers into an Array of Strings in Ruby
(Ruby,Rails) Context of Self in Modules and Libraries...
How to Find If a String Starts with Another String in Ruby
How to Get Elapsed Time in Milliseconds in Ruby
Difference Between Plugins and Ruby Gems
Getting Only New Mail from an Imap Server
Count Number of Days Between Two Dates
Ruby Invalid Byte Sequence in Utf-8
How to Generate Rdoc for (All Of) Rails
Find Classes Available in a Module
How to Add a New Action to the Existing Controller
Get Last Day of the Month in Ruby
How to Avoid Deprecation Messages from Rubygems
Changing Field Separator/Delimiter in Exported CSV Using Ruby CSV