Path: csiph.com!goblin2!goblin1!goblin.stu.neva.ru!usenet.stanford.edu!not-for-mail From: Greg Wooledge Newsgroups: gnu.bash.bug Subject: Re: looking for consistent C-c trap behavior Date: Fri, 17 Apr 2020 16:09:16 -0400 Lines: 49 Approved: bug-bash@gnu.org Message-ID: References: <20200417200916.GT845@eeg.ccf.org> NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: usenet.stanford.edu 1587154166 15354 209.51.188.17 (17 Apr 2020 20:09:26 GMT) X-Complaints-To: action@cs.stanford.edu To: bug-bash@gnu.org Envelope-to: bug-bash@gnu.org Mail-Followup-To: bug-bash@gnu.org Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 139.137.100.1 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: <20200417200916.GT845@eeg.ccf.org> X-Mailman-Original-References: Xref: csiph.com gnu.bash.bug:16153 On Fri, Apr 17, 2020 at 01:02:20PM -0700, Eduardo Bustamante wrote: > On Fri, Apr 17, 2020 at 12:59 PM gentoo_eshoes--- via Bug reports for > the GNU Bourne Again SHell wrote: > > > > I've noticed that if I trap SIGINT in a bash script, the behavior when encountering C-c depends on whether an external command (eg. 'sleep 100') or a builtin command (like 'read -p') was encountered. > > > > I attach an example script which requires me to press C-c twice to interrupt the builtin 'read -p' command, and it only works because I'm restoring the trap via 'trap - SIGINT' the first time. > > > > My goal is to have C-c interrupt and use that exit code (130 most likely) to exit with from script, regardless or whether or not the interrupted command in the script was an internal or external one. > > > > How to do? > > I recommend reading: https://www.cons.org/cracauer/sigint.html > > The problem is that the signal is sent to the foreground process. When > "sleep" is running, it's the sleep command that receives the signal > and decides what to do with it. Not bash. That's not quite right. When you press ^C in a terminal, SIGINT is sent to *all* of the processes in the "foreground" process group -- both sleep and bash, in the case you're discussing. The URL you linked to describes the behavior of bash when one of its child processes exits in a way consistent with death by SIGINT. This doesn't change the fact that bash itself *does* get the signal. The easiest way to trigger the kind of situations the cons.org page is talking about is to use an interactive shell, where SIGINT is ignored by bash, and a command that traps SIGINT in the "incorrect" way. A perfect example of this is ping. while true; do ping 127.0.0.1 done It's VERY hard to kill this loop, because each time you hit ^C, ping will be killed, but it traps SIGINT and exits by itself, so bash assumes that the SIGINT was used in a non-terminal way, and doesn't exit the loop. Compare to: while true; do sleep 10 done Terminating this loop is simple: press ^C once, and sleep is killed by SIGINT, and bash detects this, and stops the loop.