20

I have a Bash parent script that on unexpected input calls an error logging child script that logs the error. I also want the execution to halt when the error occurs and the error script is called. But if I call exit from the error handling script it does not stop the parent script from executing. How may I go about stopping a parent script from a child?

5 Answers 5

16

try..

#normal flow
[[ $(check_error_condition) ]] && /some/error_reporter.sh || exit 1

so,

  • when the error_reporter will exit with exit status > 0 the parent will terminate too
  • if the error_reporter will exit with status = 0 the parent continues...

You don't want stop the parent from a child (the parents usually don't like this behavior) :), you instead want tell to parent - need stop and he will stop itself (if want) ;)

3
  • 1
    I believe your test lacks a closing parenthesis.
    – bleistift2
    Commented Apr 5, 2020 at 14:23
  • @bleistift2 corrected after 7 years... :) :) Thanx. :)
    – clt60
    Commented Apr 7, 2020 at 18:05
  • This is very confusingly worded... I would first describe that you have to do this in parent instead, and then describe the implementation. Commented Mar 10, 2023 at 13:28
10

Try:

In parent script:

trap "echo exitting because my child killed me.>&2;exit" SIGUSR1

In child script:

kill -SIGUSR1 `ps --pid $$ -oppid=`; exit

Other way was:

In child script:

kill -9 `ps --pid $$ -oppid=`; exit

But, it is not recommended, because the parent needs to have some information about getting killed & thus do some cleanup if required.


Another way: Instead of calling the child script, exec it.


However, as pointed out in other answer, the cleanest way is to exit from parent, after the child returns.

2
  • 2
    It starts here look like in horror - the child kill the parent... :) :) (but yes, it IS a solution too) :) :)
    – clt60
    Commented Apr 25, 2013 at 13:12
  • ^^ Yups.... I once had a requirement like this: command1 | (command 2; command3) & command3 was supposed to kill command1 with SIGINT :-)
    – anishsane
    Commented Apr 25, 2013 at 13:17
0

Don't try to terminate the parent from the child. Instead call exit in the parent after the child script returned.

if [ condition ]; then
  /path/to/child.sh
  exit 1
fi

or shorter

[ condition ] && { /path/to/child.sh; exit 1; }
0

Extension to @anishsane comment because MacOS has little bit different ps syntax.

Finding parent process ID (ppid) in child script under Mac OS (Darwin):

kill -SIGUSR1 $(ps $$ -o ppid=);exit

0

Depending on your needs, using set -e at the top of your script might be a good solution. This will automatically cause the script to exit if any commands (e.g., your error checking script) exit with a non-zero exit code (https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/)

Note that there are some common commands that have non zero exit codes under normal circumstance.

Not the answer you're looking for? Browse other questions tagged or ask your own question.