running sh script on travis CI: The command exited with 1 - bash

I am running an sh script as part of my .travis.yml. It is giving me the error below although the shell script does not fail.
The command exited with 1.
I tried running the with bash -x to debug and there are no errors.
The problem is that travis thinks that the build failed although it passed.

This change fixes it.
As explained in the man bash page:
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.
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.
The last command executed is:
[ "$BUILD_CHROMIUM" == 1 ] &&_build_chromium_crx "${zip_file}" "${BUILD_METADATA[${CHROMIUM_TARGET}]}"
And it is evaluated as false with exit status 1:
'[' 0 == 1 ']'
So adding || true at the end of this line fixes it. The exit status will always be 0.
Alternatively, use the fix that better suits the expected behavior of your code like exit 0, etc.
As explained here and here:
exit [n] Cause the shell to exit with a status of n. If n is omitted,
the exit status is that of the last command executed. A trap on EXIT
is executed before the shell terminates.
So your clean function trap _clean_chrome EXIT is not the last to be executed.
Further information about exit status here.

Related

How to catch /bin/bash: bad interpreter error

recently came across an issue when running a bash script executed in a csh shell. This was outputed: /bin/bash: bad interpreter: No such file or directory. The problem was bash was not on the environment path. After adding bash, this was fixed. I want to make sure that in the future, if this ever happened again for some reason, I can handle this. I am wonder what exit code this is? or is this just printed out on stderr? I want to catch this and fail the main script. Any ideas on how to handle this?
I have this segment:
bash sc142.sh
#####################################################################
# Check for processing errors
#####################################################################
if ($status != 0) then
exit (-1)
endif
I tried this on Debian, the exit status for a bad interpreter error is 126. So you can do:
/path/to/scriptname arg ...
if ( $status == 126 ) then
echo "scriptname failed"
exit 1
endif
Note that a false positive is possible. If the last command in the script you're running exits with status 126, you won't be able to tell the difference.
The exit code will be non-zero. The exact exit code depends on the environment. You may get 127 (command not found) but you may also get another non-zero exit code in certain shells.
In your csh script you can set the -e option which will cause the script to exit immediately if any commands fail.
#!/bin/csh -e
false
echo not printed

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

shell script execution successful but output has errors, how to determine error and exit main script?

I have a main script. Inside it I call other three shell scripts, A,B and C. All were successful. Exit codes are all equal to zero. However, when I looked into the output file of the first script which is A, it contains an error message. Now I want to exit the main script and not to continue running the other scripts after the script that has output error. Can anyone help me on this? Thanks!
Even if some command in your first bash script results in an error, the script as a whole may complete with exit code 0.
You can check the exit code of any individual command in your script by using the $? variable. This variable stores the exit code of the previous command. This will allow you to check for errors within the script.
The easiest way is to append || exit 1 to the statement which is throwing the error. That will cause the script to exit if the exit code of the command is 1 (i.e. an error).
So assuming you had a command sqlscript and you wanted the entire script to exit if sqlscript exited with a non-zero exit code you would do
sqlscript || exit 1
As a point of trivia, the 1 in exit 1 is not needed. A plain exit command would also exit with the exit status of the last executed command.
Which would be false (code=1) if the sqlscript command fails. If the sqlscript command succeeds, the exit code is the exit code of sqlscript. In that case, the || does not trigger and the exit command is not executed.
I have a main script. Inside it I call other three shell scripts, A,B
and C. All were successful. Exit codes are all equal to zero. However,
when I looked into the output file of the first script which is A, it
contains an error message. Now I want to exit the main script and not
to continue running the other scripts after the script that has output
error.
Since script A doesn't return an error exit code, you have to inspect its output. This is quite easy with grep provided that you have a search string which clearly identifies an error message, e. g.:
# this echo command simulates script A - it outputs "error" and exits with 0:
echo "contains an error message" >StoreKey_All.csv # assumed this output file
grep error StoreKey_All.csv && exit 1 # exit if output has error
# continue with scripts B and C
echo B

How to terminate execution of a fish script from a sourced file?

The exit command when executed from a file being sourced doesn't terminate the execution of the program where it was being sourced, how to do this? Consider this files for a clearer explanation:
a.fish:
source b.fish
echo "This should never run!"
b.fish:
echo "Failing now"
exit 1
This will result in this (undesired output):
Failing now
This should never run!
And the exit status is 0! Is there a solution for B to terminate execution of A as if exit was written in A itself?
It's perfectly working the way you want with bash and zsh. Still, I found a solution for fish:
source b.fish; or exit 1
This will exit a.fish if b.fish exited with exit 1, and will continue otherwise.

Why do bash "set -e" cause exit after a seeming error-free command?

Without using set -e, the script runs as expected, with all results correctly generated.
After adding set -e, it exits after this command:
./NameOfATool > result.txt
When I wrap set +e and set -e around that command, then the script terminates as expected.
Why would it exit, or what might be wrong with the command?
p.s. NameOfAToolis an executable compiled from C code. When I manually type that command, it runs ok without giving an error.
set -e will cause the script to exit if any command returns a non-zero exit status. (Well, there are a bunch of exceptions, but that's the general rule.) So, ./NameOfATool apparently returns a non-zero exit status. This might mean that it actually thinks there's an error, or it might mean that the program was poorly written and doesn't report an appropriate exit status for success, or it might mean that it uses special exit-status values to report specific things (much like the standard utility diff, which returns 0 for "same", 1 for "different", and 2 for "error").
Try set +e in your trap:
set -e;
trap 'x=$?; set +e; echo Hello; false; echo World; exit 22;' ERR
echo Testing
false
echo Never See This
Omit the set +e and you don't see the "World" as the non-zero exit code in the trap exits before the trap is completed.
As #ruakh said, this indicates that the tool is exiting with a nonzero (=error) status. You can prevent this from exiting the script by putting it in a compound command that always succeeds:
./NameOfATool > result.txt || true
If the tool exits with a nonzero status, it runs true, which succeeds; hence, the entire compound command is considered to have succeeded. If the command's exit status is significant (i.e. you need to be able to tell if it exited with status 0, 1, or 2), you can either record it for later use:
./NameOfATool > result.txt && toolStatus=0 || toolStatus=$?
...or use the status directly:
if ./NameOfATool > result.txt; then
# do things appropriate for exit status = 0
else
toolStatus=$?
# do things appropriate for exit status != 0
fi

Resources