0

Say I have two scripts that just print back the return code from a useless subscript:

script1

(echo; exit 0)
echo $?

script2

(echo)
echo $?

Both give back 0. But is there a way to tell that the first subscript explicitly uses the exit command?

22
  • 2
    Not that I'm aware of. Why do you want to do this? Commented Sep 4, 2014 at 18:01
  • Just exit with a different value than 0 to indicate the exit. Commented Sep 4, 2014 at 18:02
  • 1
    I'm confused. If you run a script as the last thing you do then your exit code is the exit code of the script automatically (even if you use exit yourself). Commented Sep 4, 2014 at 18:37
  • 3
    No. Scripts don't expose when they exit, merely that they have exited with a particular code. Short of parsing the source of the script, there's no way to distinguish how a script exits. Commented Sep 4, 2014 at 19:16
  • 1
    You want call shell scripts. What if someone will implement his own trap "rm -f $tmpfile; exit" 0?! This is an common practice remove temp-files at exit, and your "exit_trap" will be overwritten. Simply, this isn't a good idea - bad logic and wrong solution and as someone already told you X-Y problem... Commented Sep 8, 2014 at 14:05

1 Answer 1

1

After some research I got some breakthrough. Namely you can setup an exit_handler that can tell if there was an exit call by simply examining the last command.

#! /bin/bash

exit_handler () {
   ret=$?
   if echo "$BASH_COMMAND" | grep -e "^exit " >> /dev/null
   then
      echo "it was an explicit exit"
   else
      echo "it was an implicit exit"
   fi
   exit $ret
}
trap "exit_handler" EXIT

exit 22

This will print

it was an explicit exit

Now in order to tell the parent, instead of echoing, we can rather write to a file, a named pipe or whatever.


As per noting of choroba, exit without an argument will give implicit call, which is admittedly wrong since exit (without argument) is the same as exit $?. For that reason the regex has to take that into consideration:

#! /bin/bash

exit_handler () {
   ret=$?
   if echo "$BASH_COMMAND" | grep -e "^exit \|^exit$" >> /dev/null
   then
      echo "it was an explicit exit"
   else
      echo "it was an implicit exit"
   fi
   exit $ret
}
trap "exit_handler" EXIT

exit 22
Sign up to request clarification or add additional context in comments.

9 Comments

You are implementing the exit_handler() in each script1 and script2. What if the last command in script2 is echo "It is now time to exit"?
I took that into consideration. It shouldn't pass with the regex ^exit since the regex allows only a command that starts with exit followed by a space. The only command that could be is exit
Looks like a good solution. I revisited the Shell Variables section of man bash. I think you hit upon a good solution. The only curiosity I have is the way it is described in BASH_COMMAND, specifically, it is the command executing at the time of the trap. Obviously it is working, but it would be reassuring to see it is the last command executed before the time of the trap. Oh well, I still like it :)
If I remove 22, I get 'implicit exit'.
"XY Problems" Happen when someone tries to solve problem X by doing Y, but cannot accomplish it so they ask the community about Y. The trouble is that Y makes no sense and the subject of the question should really be X. You've powered through Y and are on your way to posting a Z problem in the future.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.