How to exit shell script with exit 0 - bash

I am trying to run .hql file through a shell script like below
#!/bin/bash
cd /path/
hive -f hive_script.hql
but the script 'hive_script.hql' is failing . I want to exit the shell script successfully even hive_script.hql script fails. Is it possible?

If you don't put an explicit exit in your script, the exit code of your script would be the exit code of the last command it ran - in your case, it is the hive -f ... command.
You can add exit 0 at the end of your script to make sure it always exits with zero.
Related:
Raise error in Bash script

If you want the script to exit with 0 even when hive -f hive_script.hql would fail, you can just or the command with something that won't ever throw an error
hive -f hive_script.hql || :
This means that if the hive command fails, bash should also run the second command. In this case, that command is :, which is basically pass from python, and will always return a 0 status.

Related

Run a command right before a script exits due to failure

Let's say there's this script
#!/bin/zsh
python -c 'a'
which will fail since a isn't defined. Just before the shell script exits, I want to run a command, say echo bye. How can that be achieved?
Flow is to be:
Python command above fails.
bye appears in terminal.
The zsh script exits.
I'd prefer it to affect the python command as little as possible such as indent, putting it in an if block, checking its exit code etc. In real life, the command is in fact multiple commands.
In the script you posted, the fact that the shell exits is unrelated to any error. The shell would exit, because the last argument hast been executed. Take for instance the script
#!/bin/zsh
python -c 'a'
echo This is the End
The final echo will always be exeuted, independent of the python command. To cause the script to exit, when python returns a non-zero exit code, you would write something like
#!/bin/zsh
python -c 'a' || exit $?
echo Successful
If you want to exit a script, whenever the first one of the commands produces a non-zeror exit status, AND at the same time want to print a message, you can use the TRAPZERR callback:
#!/bin/zsh
TRAPZERR() {
echo You have an unhandled non-zero exit code in your otherwise fabulous script
exit $?
}
python -c 'a'
echo Only Exit Code 0 encountered

Not able exit from docker container with bash script containing exit command

I'm able to exit when I enter the exit command in container environment. But if I try to run a script file having the exit command, I'm not able to exit from the container.
1.working
ubuntu#iot-docker:/repo$ exit
exit
root#iot-docker:/repo# exit
exit
ubuntu#ubuntu-***-Twr:~/shirisha/plo-***-snt-sp_u103a3$
not working
script.sh
#!/bin/bash
exit
exit
exit is not a command to exit your container, it just exits the current shell interpreter.
When you run your script, a new shell interpreter is started according to the first line of your script (here /bin/bash). When it encounters the exit command, the interpreter stops and you get back to the command line (the previous shell).
You can make this expriment:
$ bash # Starts a new shell
$ exit # Exits the new shell; we come back to the old one
exit
$
See? Running bash in command line is similar to running your script, and exiting from it brings you back to your previous shell. You didn't exit your container.
Solution:
exec script.sh param1 ... paramN
exec will replace your current shell with the command being started (script.sh). When that command exits, you will exit your container because your old shell no longer exists.
When you script a script without "sourcing" the script, the script will be started in a new subprocess. The exit works, you will finish that subprocess.
It is important to remember, that a script starts a new environment.
Look at the script example.sh
#!/bin/bash
my_value=high
cd /tmp
Call this script with
cd $HOME
my_value="low"
./example.sh
pwd
echo "My value is now ${my_value}"
Now nothing has changed: all changes in the subprocess are gone.
You can call this script with source ./example.sh (or short . ./example.sh),
and things have changed.
When you don't want to source your script, a function (in .bashrc) might help:
example() {
my_value=high
cd /tmp
}
Now you can call the function:
cd $HOME
my_value="low"
example
pwd
echo "My value is now ${my_value}"

Exit from Shell script without executing anything

I have a shell script installed to run every day.
The script consists of some rm (delete) commands and SCP commands for file transfer. The script is failing due to some errors in production. I want the job to return exit code as 0 without executing anything, so I wrote
exit 0;
at the beginning of the shell script so that as soon as the script executes, it will exit with out any commands after that exit 0; but still the script is failing.
I cannot edit the whole contents inside the file nor delete the script or contents inside the script.
Please suggest whether I am using the right syntax for exit command or how to make the script to exit with return code 0 as soon as it starts executing.
The ';' is unnecessary. You can exit like this:
exit
exit 1
This is a description about 'Exit and Exit Status'.

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

Getting the return value in "sh -e"

I'm writing a shell script with #!/bin/sh as the first line so that the script exits on the first error. There are a few lines in the file that are in the form of command || true so that the script doesn't exit right there if the command fails. However, I still want to know know the exit code of the command. How would I get the exit code without having to use set +e to temporarily disable that behavior?
Your question appears to imply set -e.
Assuming set -e:
Instead of command || true you can use command || exitCode=$?. The script will continue and the exit status of command is captured in exitCode.
$? is an internal variable that keeps the exit code of the last command.
Since || short-circuits if command succeeds, set exitCode=0 between tests or instead use: command && exitCode=0 || exitCode=$?.
But prefer to avoid set -e style scripting altogether, and instead add explicit error handling to each command in your script.
If you want to know the status of the command, then presumably you take different actions depending on its value. In which case your code should look something like:
if command; then
# do something when command succeeds
else
# do something when command fails
fi
In that case you don't need to do anything special, since the shell will not abort when command fails.
The only reasons set -e would give you any problems is if you write your code as:
command
if test $? = 1; ...
So don't do that.

Resources