When trapsasync is set, a foreground job can be interrupted and a trap
will be executed. This can be used to kill the foreground job and
cleanup the script. At the moment, it's not possible to kill the
foreground job reliable because the pid of the foreground job is not
accessible. This patch allows a trap to get the pid by reading the $!
variable.
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Skipped - Unit
Tests Skipped - Build Status
Buildable 48637 Build 45523: arc lint + arc unit
Event Timeline
How do other shells with a similar option handle this? For example, zsh has a TRAPS_ASYNC option, but does not document how to access the interrupted job in the trap action.
When modifying a standard parameter like $!, take care to do this only if a non-standard option (such as set -T) is in use. Otherwise, a standards-compliant script might see an unexpected change. This seems to be the case.
It may be a better alternative to set the interrupted job as the current job (see the if (jp->state == JOBSTOPPED) below), making it accessible using commands like kill %+ or jobs -p %+. The latter can be used (by itself) in a command substitution. Another alternative may be to set a new variable.
bin/sh/jobs.c | ||
---|---|---|
1096 | Only setting backgndpid and not adjusting bgjob will cause evaluating $! to return one job's process ID but cause another job to be remembered. | |
1096 | $! is normally set to the last process's ID, not the first. This indeed does not match the job's process group ID for pipelines with two or more processes. |
Thanks for the hint. kill %+ and jobs -p %+ are already working. So, no patch required. Might be a good idea to mention it in the man page.
Feel free to submit a patch for that.
By the way, this will not work if there is a stopped (^Z'ed) job, because %+ (and also %-) will refer to a stopped job when possible.