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)
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  Edit
Everyone can see this information.

Other bug subscribers