2

My script looks like:

trap "$(pwd)/dd-destroy.sh $l-env;$(pwd)/dd-drop.sh $l-db;exit" INT QUIT TERM EXIT
./dd-all.sh $l $l-db $l-env || exit 1
app_ip=$(./dd-status.sh ip $l-env|grep docker-app|awk '{print 3ドル}')
url=http://$app_ip:8080/app/
wget -O /dev/null $url || (echo "access $url failed" && false) || exit 1

Now I want this trap launch when error occurs, those 'exit 1' (I can change them there). But when nothing happens, like dd-all.sh worked fine, when wget came fine. I do not want to call for destroy.

Can I accomplish this with trap? It's not my script, I need to change it a little. Maybe trap is a bad call here?

Jeff Schaller
68.8k35 gold badges122 silver badges263 bronze badges
asked Oct 1, 2015 at 14:25
3
  • 1
    trap specifies which signals the dd-destroy.sh... command should be invoked on. I don't know of any way for that command to test what the error code was when getting an EXIT signal. I'd recommend creating a function that has your dd-destroy.sh ... stuff in it; have the trap line invoke that function but omit the signal EXIT; and replace your exit 1 with { that_function; exit 1; }. Commented Oct 1, 2015 at 14:52
  • Why are you listing EXIT in the trap specification if you don't want the trap to run on exit? Commented Oct 2, 2015 at 10:45
  • @tripleee the OP wants the trap to run on normal (non-signalled) exits but only when the exit code is > 0. Commented Oct 4, 2015 at 1:24

1 Answer 1

4

Simply change the start of your trap to check for the return code of the last command (which will be that of the exit, or the command at the end of the script) for zero. I.e.

trap '[ $? = 0 ] && exit;'"..."

where "..." is your current string, which should follow with no intervening spaces. An exit within the trap will not trap again.

If your trap is also handling signals, eg SIGINT (control-C), then the trap is called once for the SIGINT, then once more for the exit. You can probably check if trap is being called from SIGINT as the $? will be 128+n where n is the signal, so 130 for SIGINT. Remember $? will be changed as soon as you give another command, so perhaps start with rc=$?; then use $rc in your tests.

answered Oct 1, 2015 at 17:55
3
  • Huh, I was skeptical, but I just confirmed you are right. Tested on a v3 bash as well as a BusyBox sh (variant of ash), works as you say in both cases. Commented Oct 1, 2015 at 20:27
  • Great thx, but there's still a little problem that I do not understand. 'trap '[ $? = 0 ] && exit;'"echo 'DUPA'" INT QUIT TERM EXIT </br> sleep 2 when I hit ctrl+c, i see 'dupa' printed twice. Why's that? Is trap handled twice then? When? Commented Oct 2, 2015 at 6:55
  • Yes, trap is called once for the sigint, then once for the exit. You can probably check if trap is being called from sigint as the $? will be 128+n where n is the signal, so 130 for sigint. Remember $? will be changed as soon as you give another command, so perhaps start with rc=$?; then use $rc. Commented Oct 2, 2015 at 7:16

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.