OK to omit "exit 0" at end of Ruby script? - ruby

On Ubuntu 14's Ruby 1.9.3, when I run the script
#!/usr/bin/env ruby
and the script
#!/usr/bin/env ruby
exit 0
they do the same thing. In particular, a subsequent echo $? prints 0. How universal is this behavior? Can I safely omit exit 0 from the end of a nontrivial script?

Universally in UNIX, 0 is reserved for success and codes other than 0 - different sorts of errors.
In any normal language, unless your program throws some sort of exception or explicitly exits with a different code, you can safely assume that it exited with 0.
As per the documentation of Process#exit:
exit(status=true)
[...]The optional parameter is used to return a status code to the invoking environment. true and FALSE of status means success and failure respectively.
The interpretation of other integer values are system dependent.
Meaning Ruby exits with success by default, whatever success means for the underlying system.
As per the documentation of exit codes from The Linux Documentation Project:
[...] A successful command returns a 0, while an unsuccessful one returns a non-zero value that usually can be interpreted as an error code. Well-behaved UNIX commands, programs, and utilities return a 0 exit code upon successful completion, though there are some exceptions. [...]
Meaning you are will get 0 in a UNIX environments.
As per Microsoft's documentation on exit codes:
ERROR_SUCCESS
0 (0x0)
The operation completed successfully.
Meaning you will also get zero in Windows.

Related

Could the shell function return value not exceed 255? [duplicate]

This question already has answers here:
ExitCodes bigger than 255, possible?
(3 answers)
Return value range of the main function
(7 answers)
Closed 4 years ago.
#!/usr/bin/env bash
# set -x
readonly err_code=256
my_function () {
return $err_code
}
my_function
echo $? # print 0
If the err_code exceed the 255, all the top bits will be dropped just like unsigned byte, how to explain this? Is there any feature document for this? I googled a lot w/o luck.
Thanks!
UPDATE:
Okay, I got it, it doesn't just happen only in shell but Unix-based system, the shell function is also called by command substitution.
Thanks for linked questions!
If you look at man bash and search for EXIT STATUS you will find the following explanation:
EXIT STATUS
The exit status of an executed command is the value returned by the waitpid system call or equivalent
function. Exit statuses fall between 0 and 255, though, as explained below, the shell may use values
above 125 specially. Exit statuses from shell builtins and compound commands are also limited to this
range. Under certain circumstances, the shell will use special values to indicate specific failure modes.
For the shell's purposes, a command which exits with a zero exit status has succeeded. An exit status of
zero indicates success. A non-zero exit status indicates failure. When a command terminates on a fatal
signal N, bash uses the value of 128+N as the exit status.
If a command is not found, the child process created to execute it returns a status of 127. If a command
is found but is not executable, the return status is 126.
If a command fails because of an error during expansion or redirection, the exit status is greater than
zero.
Shell builtin commands return a status of 0 (true) if successful, and non-zero (false) if an error occurs
while they execute. All builtins return an exit status of 2 to indicate incorrect usage, generally
invalid options or missing arguments.
Bash itself returns the exit status of the last command executed, unless a syntax error occurs, in which
case it exits with a non-zero value. See also the exit builtin command below.
If you really want to return values greater than 125, you can use echo instead of return like this:
#!/usr/bin/env bash
my_function () {
echo 256
}
retval=$( my_function )
echo $retval

What does $? mean immediately after trying to execute an invalid command in the Bourne shell?

I know the $? means the return value of the lastly executed command. I was curious; if the command is invalid, then what will $? be?
It was 127. What does it mean? Why is it 127?
> echo a
a
> echo $?
0
> invalidcommandasdf
invalidcommandasdf: not found
> echo $?
127
The exit status does double duty: it might return information from a program, but it also might return information from whoever ran the program about how the program exited. While a program can, in theory, have any exit code in the range 0 to 255, many of them are assigned special meaning by, say, the POSIX standard, and are not available for use by the program itself.
126 and 127, for instance, are for use by the shell (or other command runner) running the command. 127 means the command could not be found, and 126 means the command was found, but wasn't executable.
Any exit status greater than 128 indicates the program exited due to a signal: 129 when it exits due to signal 1, 130 due to signal 2, etc. In general, 128 + k means it exited due to signal k.
(I'm not sure if 128 itself is reserved for anything in particular.)
In practice, this means your command should not explicitly use any exit code greater than 125. That generally shouldn't be a problem; most commands don't need to distinguish between 125 different errors (0, of course, means it exited without error.) curl is an example of a program that uses a lot of different codes, but even it only uses most of the available values between 1 and 90.
$? gives the exist status code of last executed command/process. 127 status code means Command Not found
for more detail : bash-shell-exit-status/
The primary use of "$?" is to check if the last run command has exit value true or false. You will get output as '0' or '1' where '0' is returned if the last run command is true and '1' if its false.
For unknown commands you will get output such as you have shown.
You can try this by simple using random string (sajdgh / uytwegf) as unrecognized commands and you can see you get a different output.
However the primary use of this command is check the logical status of last used command. Fire ls and see the output of "echo $?" will be '0' now just try 'cat unknown.txt' (considering you actually dont have file named 'unknown.txt') you will get output as '1'

bash exit code out of range

I'm a bit confused about these kinds of Bash exit codes.
For example:
# (exit 444)
then when I use echo command to show exit code:
# echo $?
this is gonna result it : 188
It seems that it is a result from 444-256.I know that exit codes range is 0-255.So they will count as 256 exit codes in total.
But when I use:
(exit 555)
what calculation occurs? This returns 43 as exit code.
You are experiencing the effect of 8-bit integer overflow. After 255 (all 8 bits set) comes 0 (no bits set).
So the calculation you're seeing is "exit code modulo 256".
From the Bash manual, emphasis mine:
Exit Status
The exit status of an executed command is the value returned by the waitpid system call or equivalent function. Exit statuses fall between 0 and 255, though, as explained below, the shell may use values above 125 specially. Exit statuses from shell builtins and compound commands are also limited to this range. Under certain circumstances, the shell will use special values to indicate specific failure modes.
The last part becomes important once signals come into play, which may interrupt a process and give an exit code of...
...128+n if the command is terminated by signal n...
...but that's the shell at work, not the exit command (which does not allow those values).

Get Ruby to identify if child process get a segfault

I am running Ruby as a wrapper to an EDA tool, in RH5.The tool segfaulted. However, the command line did not show any indication. Only when running the command that Ruby launched, did we learn that the segfault happened. How can I get the segfault message within the wrapper?
Thanks.
From Kernel#system documentation:
system returns true if the command gives zero exit status, false for non zero exit status. Returns nil if command execution fails. An error status is available in $?.
So, if you just want to make sure that everything went ok, you just check if the return value of system was true. If you want to specifically check if there was a segmentation fault, then the return value will be false and $: will be like this:
puts $?
#=> pid 3658 SIGSEGV (signal 11)

Why do we pass 0 as a parameter to "exit"?

In the book learn ruby the hard way, I found a syntax to exit from the program:
Process.exit(0)
Why is the parameter 0 being passed in the exit method here even though it works if I pass another integer or do not pass any parameter? What is the significance of 0?
This is an 'exit code'.
This exit code has special meaning in some cases (see for example http://tldp.org/LDP/abs/html/exitcodes.html)
You can pass whatever you want, if the code isn't caught after, this will have no effects.
Here '0' is for 'Everything works fine !'
It is because when a child process is started (child process being your Ruby script in that case) the parent process (shell, system, etc.) can wait for it to finish.
Once it's finished, it can tell the parent process what is the status of it's execution. Zero usually means that the execution has been successfull and completed without any errors.
If you, on example, run your script from bash shell, and it will call Process.exit(0), you could check if it succeeded using $? variable:
$ ./my_ruby.script # calls Process.exit(0)
$ echo $?
0 # ok, script finished with no errors.

Resources