Ruby and exit codes Ruby's default exit value is 0 if we want to send a different exit value we should use the exit method. The exit method receives as a parameter a true or false value if the value is an integer that would be the returned value of our script.
Launch a terminal, and run any command. Check the value of the shell variable “$?” for the exit code. $ echo $? As the “date” command ran successfully, the exit code is 0.
When you execute a command or run a script, you receive an exit code. An exit code is a system response that reports success, an error, or another condition that provides a clue about what caused an unexpected result from your command or script.
To check the exit code we can simply print the $? special variable in bash. This variable will print the exit code of the last run command.
From the documentation:
system returns
true
if the command gives zero exit status,false
for non zero exit status. Returnsnil
if command execution fails.
system("unknown command") #=> nil
system("echo foo") #=> true
system("echo foo | grep bar") #=> false
Furthermore
An error status is available in
$?
.
system("VBoxManage createvm --invalid-option")
$? #=> #<Process::Status: pid 9926 exit 2>
$?.exitstatus #=> 2
For me, I preferred use `` to call the shell commands and check $? to get process status. The $? is a process status object, you can get the command's process information from this object, including: status code, execution status, pid, etc.
Some useful methods of the $? object:
$?.exitstatus => return error code
$?.success? => return true if error code is 0, otherwise false
$?.pid => created process pid
system
returns false
if the command has an non-zero exit code, or nil
if there is no command.
Therefore
system( "foo" ) or exit
or
system( "foo" ) or raise "Something went wrong with foo"
should work, and are reasonably concise.
You're not capturing the result of your system
call, which is where the result code is returned:
exit_code = system("ruby test.rb")
Remember each system
call or equivalent, which includes the backtick-method, spawns a new shell, so it's not possible to capture the result of a previous shell's environment. In this case exit_code
is true
if everything worked out, nil
otherwise.
The popen3
command provides more low-level detail.
One way to do this is to chain them using and
or &&
:
system("VBoxManage createvm --name test1") and system("ruby test.rb")
The second call won't be run if the first fails.
You can wrap those in an if ()
to give you some flow-control:
if (
system("VBoxManage createvm --name test1") &&
system("ruby test.rb")
)
# do something
else
# do something with $?
end
I want something like
system("VBoxManage createvm --name test1", 0)
<-- where the second parameter checks the exit code and confirms that that system call was successful, and if not, it'll raise an error or do something of that sort.
You can add exception: true
to your system
call to have an error raised on non 0 exit codes.
For example, consider this small wrapper around system
which prints the command (similar to bash -x
, fails if there's a non 0 exit code (like bash -e
) and returns the actual exit code:
def sys(cmd, *args, **kwargs)
puts("\e[1m\e[33m#{cmd} #{args}\e[0m\e[22m")
system(cmd, *args, exception: true, **kwargs)
return $?.exitstatus
end
To be called like: sys("hg", "update")
If you want to call a program that uses a different convention for exit codes, you can suppress raising the exception:
sys("robocopy", src, dst, "/COPYALL", "/E", "/R:0", "/DCOPY:T", exception: false)
You can also suppress stdout and stderr for noisy programs:
sys("hg", "update", "default", :out => File::NULL, :err => File::NULL)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With