Dash Archive mirror
 help / color / mirror / Atom feed
* EXIT trap does not fire
@ 2022-05-31 20:39 charles.fisher
  2022-05-31 21:57 ` Paul Smith
  0 siblings, 1 reply; 5+ messages in thread
From: charles.fisher @ 2022-05-31 20:39 UTC (permalink / raw
  To: dash

I think that I have found a bug in dash that impacts EXIT trap handling. The behavior is different (and appears correct) in bash, ksh93 and mksh. I am using the EPEL dash package, version 0.5.10.2 for CentOS 7 (full package info included).

I didn't see this already reported on the mailing list; hopefully I am not reporting a duplicate bug, sorry if so.

The ssh-agent used in the context immediately below seems to prevent an EXIT trap from firing upon abnormal termination:

  # cat dashbug_trivial
  #!/bin/dash

  eval $(ssh-agent)

  trap 'eval $(ssh-agent -k)' EXIT

  if ssh-add
  then echo testing
       read junk
  fi

The EXIT does not fire if the user aborts (it fires properly if the user does not abort):

  # ./dashbug_trivial 
  Agent pid 59714
  Enter passphrase for /root/.ssh/id_ed25519: 
  Identity added: /root/.ssh/id_ed25519 (root@bastion.mycompany.com)
  testing
  ^C
  # ps ax | grep agent | grep -v grep
  59714 ?        Ss     0:00 ssh-agent


I am actually iterating over a set of hosts inside the conditional:

  # cat dashbug
  #!/bin/dash

  eval $(ssh-agent)

  trap 'eval $(ssh-agent -k)' EXIT

  if ssh-add
  then while read -r host port user <&9
       do printf '=%s=%d=%s=\n' "$host" "$port" "$user"
          ssh -p "$port" "$user@$host" "$@" 2>&1
       done 9<<-''EndOfHosts
	limsprd.amppcs.noa.alcoa.com 22 root
	darkstar.dpw.alcoa.com 24 root
  EndOfHosts
  fi

The iterative script executes perfectly in dash; the problem is abnormal termination:

  # ./dashbug uptime
  Agent pid 10809
  Enter passphrase for /root/.ssh/id_ed25519: 
  Identity added: /root/.ssh/id_ed25519 (root@bastion.mycompany.com)
  =host1.mycompany.com=22=root=
  13:12:52 up 233 days,  1:58,  0 users,  load average: 0.66, 0.63, 0.54
  =host2.mycompany.com=24=root=
  13:12:52 up 2 days,  1:59,  0 users,  load average: 0.00, 0.00, 0.00
  Agent pid 10809 killed

Oddly, when I left off the trailing "fi" the trap killed the agent:

  # ./dashbug uptime
  Agent pid 9953
  ./dashbug: 15: ./dashbug: Syntax error: end of file unexpected (expecting "fi")
  Agent pid 9953 killed

When I break the password prompt with a control-c, dash does not terminate the agent:

  # ./dashbug uptime
  Agent pid 10072
  Enter passphrase for /root/.ssh/id_ed25519: ^C

  #

I confirmed this with a check of the process list:

  # ps ax | grep agent | grep -v grep
  10072 ?        Ss     0:00 ssh-agent

If I switch this to mksh (or other previously mentioned shells), a control-c does what I expect:

  # head -1 dashbug
  #!/bin/mksh

  # ./dashbug uptime
  Agent pid 10193
  Enter passphrase for /root/.ssh/id_ed25519: ^C
  Agent pid 10193 killed
  #

Is this a problem with dash, or a lack in my understanding?


These are the full details on the CentOS 7 EPEL package for dash:

  # rpm -qi dash
  Name        : dash
  Version     : 0.5.10.2
  Release     : 1.el7
  Architecture: x86_64
  Install Date: Wed 11 Aug 2021 01:45:26 PM CDT
  Group       : System Environment/Shells
  Size        : 159742
  License     : BSD and GPLv2+ and Public Domain and Copyright only
  Signature   : RSA/SHA256, Mon 05 Nov 2018 06:00:50 AM CST, Key ID 72f97b74ec551f03
  Source RPM  : dash-0.5.10.2-1.el7.src.rpm
  Build Date  : Mon 05 Nov 2018 06:00:48 AM CST
  Build Host  : x86-ol7-builder-01.us.oracle.com
  Relocations : (not relocatable)
  Vendor      : Oracle America
  URL         : http://gondor.apana.org.au/~herbert/dash/
  Summary     : Small and fast POSIX-compliant shell
  Description :
  DASH is a POSIX-compliant implementation of /bin/sh that aims to be as small as
  possible. It does this without sacrificing speed where possible. In fact, it is
  significantly faster than bash (the GNU Bourne-Again SHell) for most tasks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: EXIT trap does not fire
  2022-05-31 20:39 EXIT trap does not fire charles.fisher
@ 2022-05-31 21:57 ` Paul Smith
  2022-06-01 12:47   ` Steffen Nurpmeso
  0 siblings, 1 reply; 5+ messages in thread
From: Paul Smith @ 2022-05-31 21:57 UTC (permalink / raw
  To: charles.fisher, dash

On Tue, 2022-05-31 at 16:39 -0400, charles.fisher@arconic.com wrote:
> The ssh-agent used in the context immediately below seems to prevent
> an EXIT trap from firing upon abnormal termination:

Unfortunately it's not clearly specified in the standard what should
happen in this situation.  There is an open issue about this:

https://austingroupbugs.net/view.php?id=621

and here it's pointed out that many shells do not run the EXIT trap
when a signal is received, but a few do (bash is one of the few).  So,
this is just an unfortunately unclear area of the standard and shells
choose to do different things depending on what they interpret "exit"
to mean: if they interpret it to mean only "normal exit, by someone
running exit or reaching EOF" then they will behave as dash does.  If
they interpret it to mean "the shell process is going away for any
reason", then they'll interpret it as bash does.

You can, of course, add multiple conditions:

   trap ... EXIT INT ABRT KILL TERM

or similar so both possibilities are catered to.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: EXIT trap does not fire
  2022-05-31 21:57 ` Paul Smith
@ 2022-06-01 12:47   ` Steffen Nurpmeso
  0 siblings, 0 replies; 5+ messages in thread
From: Steffen Nurpmeso @ 2022-06-01 12:47 UTC (permalink / raw
  To: Paul Smith; +Cc: charles.fisher, dash

Paul Smith wrote in
 <c9c96d88c226cc9db0d447fc1160608a6c5e0362.camel@mad-scientist.net>:
 |On Tue, 2022-05-31 at 16:39 -0400, charles.fisher@arconic.com wrote:
 |> The ssh-agent used in the context immediately below seems to prevent
 |> an EXIT trap from firing upon abnormal termination:
 |
 |Unfortunately it's not clearly specified in the standard what should
 |happen in this situation.  There is an open issue about this:
 |
 |https://austingroupbugs.net/view.php?id=621
 |
 |and here it's pointed out that many shells do not run the EXIT trap
 |when a signal is received, but a few do (bash is one of the few).  So,
 |this is just an unfortunately unclear area of the standard and shells
 |choose to do different things depending on what they interpret "exit"
 |to mean: if they interpret it to mean only "normal exit, by someone
 |running exit or reaching EOF" then they will behave as dash does.  If
 |they interpret it to mean "the shell process is going away for any
 |reason", then they'll interpret it as bash does.
 |
 |You can, of course, add multiple conditions:
 |
 |   trap ... EXIT INT ABRT KILL TERM

I do

  trap "echo on exit" EXIT
  trap "trap '' INT HUP QUIT TERM; exit 1" INT HUP QUIT TERM

So whether it truly protects everywhere i do not know.

 |or similar so both possibilities are catered to.
 --End of <c9c96d88c226cc9db0d447fc1160608a6c5e0362.camel@mad-scientist.net>

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: EXIT trap does not fire
@ 2022-11-12 11:02 Akbarkhon Variskhanov
  2022-11-12 12:02 ` Harald van Dijk
  0 siblings, 1 reply; 5+ messages in thread
From: Akbarkhon Variskhanov @ 2022-11-12 11:02 UTC (permalink / raw
  To: dash

I can confirm this behavior in dash
0.5.11+git20210903+057cd650a4ed-3build1 (on Ubuntu).

Signal terminations are not caught by EXIT. It only catches normal
exits. Unfortunately, the EXIT condition is not well-defined by POSIX,
so it's left to interpretation. In the EXAMPLES section of `trap`,
it's hinted that EXIT should be able to handle all terminations (thus,
acting like a shortcut):

> Set a trap so the logout utility in the directory referred to by the HOME environment variable executes when the shell terminates:
>   trap '"$HOME"/logout' EXIT

In dash:

#!/bin/dash
> /tmp/file
trap 'rm -f /tmp/file' EXIT
read -r input

the action is never executed if the script is sent any terminating
signal (HUP, ABRT, INT, TERM, you name it).

In bash, however, it seems to work fine. The action is executed and
the exit status is preserved.

I'm not sure what The Open Group is planning to do and whether or not
we're getting any clarification regarding this. Until then, I think
it's reasonable to interpret or even expect that the EXIT condition
concerns all kinds of terminations, not just explicit program exits.

To conclude, I just wanna say that

     trap 'cleanup' EXIT

is shorter/cleaner/better/saner than

     trap 'cleanup' HUP ABRT INT QUIT TERM KILL PIPE ...

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: EXIT trap does not fire
  2022-11-12 11:02 Akbarkhon Variskhanov
@ 2022-11-12 12:02 ` Harald van Dijk
  0 siblings, 0 replies; 5+ messages in thread
From: Harald van Dijk @ 2022-11-12 12:02 UTC (permalink / raw
  To: Akbarkhon Variskhanov, dash

Hi,

On 12/11/2022 11:02, Akbarkhon Variskhanov wrote:
> In bash, however, it seems to work fine. The action is executed and
> the exit status is preserved.

This is not actually the case. bash will run EXIT actions on any signal 
that it installs a handler for, but it does not install a handler for 
all signals.

   $ bash -c 'trap "echo exit" EXIT; kill -PWR $$; echo still here'
   Power failure
   $ bash -c 'trap "echo exit" EXIT; trap "exit" PWR; kill -PWR $$; echo 
still here'
   exit

> I'm not sure what The Open Group is planning to do and whether or not
> we're getting any clarification regarding this.

POSIX is making it unspecified what happens here:

   https://austingroupbugs.net/view.php?id=621

     The EXIT condition shall occur when the shell terminates normally
     (exits), and may occur when the shell terminates abnormally as a
     result of delivery of a signal (other than SIGKILL) whose trap
     action is the default.

The original proposed resolution listed a number of signals that would 
be required to be caught and to have EXIT handlers run. There were 
objections to that proposed resolution, it seemed unreasonable to 
require shells to install signal handlers for signals that scripts do 
not explicitly request signal handlers for.

Cheers,
Harald van Dijk

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-11-12 12:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-31 20:39 EXIT trap does not fire charles.fisher
2022-05-31 21:57 ` Paul Smith
2022-06-01 12:47   ` Steffen Nurpmeso
  -- strict thread matches above, loose matches on Subject: below --
2022-11-12 11:02 Akbarkhon Variskhanov
2022-11-12 12:02 ` Harald van Dijk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).