0

Let's say I have a shell and another external shell. On the first shell I run bash: This is the parent bash. In the parent bash I set a trap with trap exit INT for example. Then I run bash again inside this parent bash, so I get a child bash where I do whatever. Then from the external shell, if I try to kill the parent bash's PID with -INT flag it does not do anything. Once I exit the child bash then it returns to the parent bash and executes the trap and kills the parent bash right away.

My main question is How can I force a trap to be executed right away, even if the corresponding bash has some subshells open? How can I work around it? I don't want brutal execution like -9 since I still want my bash's trap to do specific clean up work.

INT doesnt seem to matter. Example: In one shell run:

bash
ps
trap "echo HELLO" TERM
bash

In the other shell write:

kill -TERM (pid that you read in ps)

it won't do anything until you actually exit the child bash

jam
  • 803
  • 5
  • 14
  • One way around it could be storing reference information of the subshells and info needed to do the clean up work. But I don't want to do that. This is tedious, in the parent bash, all the information needed is already loaded in memory and it would be much more convenient to just resume execution in the trap. How can I do that? – jam Jan 12 '18 at 18:47
  • I tried launching the child bash with bash & to make it in the background hoping it would allow parallel execution of my parent bash but it did not work. – jam Jan 12 '18 at 18:52
  • INT is not important here I tried with other signals and they delay trap execution too. – jam Jan 12 '18 at 19:03
  • 1
    See [When is a signal handled?](http://mywiki.wooledge.org/SignalTrap#When_is_the_signal_handled.3F) – Charles Duffy Jan 12 '18 at 19:11
  • @CharlesDuffy When I do what they do with bash instead of sleep: bash & wait $! , then I call kill with -TERM signal, I get a segmentation fault – jam Jan 12 '18 at 19:26
  • A segfault is always a bug -- not in your code, but in the build of bash you're using. Easy answer is to not use that build, and report the bug upstream if it's able to be reproduced on a current release (or upstream to your distro, if it's reliably reproducible on the latest distro package but not upstream). – Charles Duffy Jan 12 '18 at 20:15
  • BTW, it sounds to me like your real use case has details you aren't describing here (that you want to have a number of subprocesses and do subprocess-specific cleanup, f/e). There are liable to be techniques available that allow a clean implementation for your use case (such as storing a sparse array mapping PIDs for individual subshells to the data needed to run the cleanup of same), if we knew enough about your real intent to be able to address it. – Charles Duffy Jan 12 '18 at 20:20

1 Answers1

-1

You're running into the special handling tht shells do for keyboard interrupts (SIGINT and SIGQUIT). These signals are sent by the terminal to entire process groups, but should in general just kill the 'foreground' process in the group.

The way this actually works is that when a shell (any shell, not just bash) invokes a child (any child process, shell or executable or whatever) and immediately waits for the child's completion (a foreground command in the shell), while it is waiting, it ignores SIGINT (and SIGQUIT) signals. Once the child completes (which may be due to the child exiting from the SIGINT signal from the keyboard), the shell becomes foreground again and no longer ignores SIGINT/SIGQUIT.

The takeaway from this is that you should not use the keyboard control signals for things other than keyboard control actions. If you want to terminate the parent shell regardless of its state, use a SIGTERM signal. That's what the TERM signal is for.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • using -TERM instead did not solve my problem. it still waits for the child shell to finish – jam Jan 12 '18 at 18:59
  • It works as expected for me -- if you're seeing different behavior, you'll need to show an mvce that demonstrates your problem. – Chris Dodd Jan 12 '18 at 19:05
  • Please see my edit – jam Jan 12 '18 at 19:11
  • @ChrisDodd, can you please provide some links supporting this answer? It's contrary to my experience, contrary to [the Wooledge wiki's SignalTrap page](http://mywiki.wooledge.org/SignalTrap#When_is_the_signal_handled.3F), and contrary to other content on this site (indicating that *all* trappable signals are deferred when external commands are running). – Charles Duffy Jan 12 '18 at 19:16