dash "set -e" breaks "trap action INT"

Bug #673119 reported by danmb
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
dash (Ubuntu)
Confirmed
Undecided
Unassigned

Bug Description

Binary package hint: dash

With set -e, dash executes only the first command of an INT (Ctrl-C) trap handler:

#!/bin/sh
set -e

trap 'sorry' INT
trap 'echo EXIT' EXIT

zero() {
  return 0;
}

sorry() {
  #zero
  echo "Ignored 1"; echo "Ignored 2"
  sleep 1
  echo Back
}

for i in 3 2 1; do
    echo "$i"
    sleep 1 # || true
done

echo OUT

Actual result:

$ ./x # Press ^C right away
3
^CIgnored 1
EXIT

Expected result:

3
^CIgnored 1
Ignored 2
Back
2
1
OUT
EXIT

By un-commenting the call to function zero, or the "|| true" in the main loop, the problem disapears.

Bash also exits prematurely, but at least it runs the "trap INT" handler code to completion.

ProblemType: Bug
DistroRelease: Ubuntu 10.04
Package: dash 0.5.5.1-3ubuntu2
ProcVersionSignature: Ubuntu 2.6.32-25.45-generic 2.6.32.21+drm33.7
Uname: Linux 2.6.32-25-generic i686
NonfreeKernelModules: nvidia
Architecture: i386
Date: Tue Nov 9 19:12:41 2010
ProcEnviron:
 PATH=(custom, user)
 LANG=en_US.UTF-8
 SHELL=/bin/bash
SourcePackage: dash

Revision history for this message
danmb (danmbox) wrote :
Revision history for this message
danmb (danmbox) wrote :

I have reported this bug upstream and it has been confirmed.

http://<email address hidden>/msg00401.html

Apparently dash 0.5.6 fixes it, but releases up to Natty still use 0.5.5

tags: added: maverick natty
Revision history for this message
ZoFreX (zofrex) wrote :

This bug is... now different. But not fixed. Using Dash 0.5.8-2.10, the output I get from the script is:

3
^CEXIT
Ignored 1
Ignored 2
Back

Note that EXIT fires a lot earlier than expected, and the script unexpectedly terminates.

I still see similar behaviour to the original bug (only one line is executed) with this script:

#!/bin/sh
set -e

trap 'exit 1' INT
trap 'sorry' EXIT

sorry() {
  echo "Ignored 1"; echo "Ignored 2"
  sleep 1
  echo Back
}

for i in 3 2 1; do
    echo "$i"
    sleep 1 # || true
done

echo OUT

Expected output:

3
^CIgnored 1
Ignored 2
Back

Actual output:

3
^CIgnored 1

Revision history for this message
Jarno Suni (jarnos) wrote :

Output by dash 0.5.10.2-6:
3
^CIgnored 1
Ignored 2
Back
EXIT

bash 5.0.3 works the same way.

To get the output you want, you can use the following code:
--------------
#!/bin/sh
#set -e

trap '' INT
trap 'echo EXIT' EXIT

sorry() {
  echo "Ignored 1"; echo "Ignored 2"
  sleep 1
  echo Back
}

for i in 3 2 1; do
    echo "$i"
    (
  trap 'sorry; exit 0' INT
  sleep 1
    ) # || :
done

echo OUT
---------

If you use bash, instead of dash, it would work even if "set -e" was used and "trap '' INT" was not used. If "set -e" was used with dash, you would have to uncomment "|| :" to make it work.

See also Bug #892317

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in dash (Ubuntu):
status: New → Confirmed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.