Re: SIGINT handling
On Mon, Sep 21, 2015 at 10:07:55PM +0100, Stephane Chazelas wrote: > Maybe the test scenario was not clear: > > bash -c 'cmd; echo hi' > > is run from an interactive shell, cmd is a long running > application (the problem that sparked this discussion was with > ping and I showed examples with an inline-script calling sleep) Just for the record, ping is the *classic* example of an incorrectly written application that traps SIGINT but doesn't kill itself with SIGINT afterward. (This seems to be true on multiple systems -- at the very least, HP-UX and Linux pings both suffer from it.) A loop like this works as expected: while true; do sleep 1 done A loop like this does not: while true; do ping -c 1 some.host # or on HP-UX, ping some.host -n 1 done You might already have been aware of this; I'm not sure. But in any case, it makes a tremendous different what "cmd" is in your example. You can't generalize it.
Re: SIGINT handling
2015-09-22 08:18:08 -0400, Greg Wooledge: [...] > You might already have been aware of this; I'm not sure. But in any case, > it makes a tremendous different what "cmd" is in your example. You > can't generalize it. Hi Greg, Yes, this whole thread is about the behaviour of uninteractive bash with commands that call exit() upon SIGINT. It was initially a follow-up on https://unix.stackexchange.com/questions/230421/unable-to-stop-a-bash-script-with-ctrlc/230568#230568 which was about ping specifically. It's true that with shells implementing WCE, the behaviour of ping is unfortunate, but I don't think we can say that ping is to blame, more WCE. ping cannot exit other than on error or when killed. It seems reasonable for it to exit (after printing the statistics) if there was no error upon CTRL-C. Note that the iputils version does a exit(!nreceived || (deadline && nreceived < npackets)); It it returning information to the caller which it couldn't do if it killed itself. That allows system("ping something") for instance to make use of the return status (system(3) ignores SIGINT in the parent). The WCE behaviour is cause for a number of bugs like that so I'm not sure it's such a great idea. -- Stephane
Re: SIGINT handling
On 9/21/15 5:24 PM, Stephane Chazelas wrote: > 2015-09-21 15:34:28 -0400, Chet Ramey: >> On 9/21/15 5:48 AM, Stephane Chazelas wrote: >> >>> I'm not sure I prefer that WCE approach over WUE. Wouldn't it be >>> preferable that applications that intercept SIGINT/QUIT/TSTP for >>> anything other than clean-up before exit/suspend implement job >>> control themselves instead (like vi's :! should create a process >>> group and make that the foreground process group of the >>> terminal so pressing ^C in sh -c vi, :!sleep 10, only sends the >>> SIGINT to sleep)? >> >> The classic example is emacs remapping the terminal intr key to ^G >> and using SIGINT as its internal abort-command signal. > [...] > > AFAICT emacs starts a new process group (and makes it the > foreground process group). Maybe, if it's being run from an interactive shell or in a separate X window. On the other hand, run this script with `dash': echo before emacs -nw /tmp/qux echo after If you use ^G to abort an editing command in emacs, you won't see `after' displayed and the script will exit with status 130, even though emacs clearly doesn't die due to SIGINT. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: SIGINT handling
2015-09-22 09:41:35 -0400, Chet Ramey: [...] > > AFAICT emacs starts a new process group (and makes it the > > foreground process group). > > Maybe, if it's being run from an interactive shell or in a separate > X window. On the other hand, run this script with `dash': > > echo before > emacs -nw /tmp/qux > echo after > > If you use ^G to abort an editing command in emacs, you won't see `after' > displayed and the script will exit with status 130, even though emacs > clearly doesn't die due to SIGINT. [...] It works for me (on Debian, displays both before and after) as emacs starts in a new process group. The problem seems to be with some ports of emacs to OS/X and was already discussed at http://www.zsh.org/mla/workers/2009/msg00926.html about the MacPorts version of Emacs that doesn't seem to be starting the new process group. -- Stephane
Re: SIGINT handling
2015-09-22 09:41:35 -0400, Chet Ramey: [...] > > AFAICT emacs starts a new process group (and makes it the > > foreground process group). > > Maybe, if it's being run from an interactive shell or in a separate > X window. On the other hand, run this script with `dash': [...] It does that unconditionaly (since 94 at least), but that's under a #ifdef BSD_PGRPS in the emacs source. Strangely enough, that BSD_PGRPS is not defined anymore for freebsd or netbsd though it is for gnu-linux It seems it's because the meaning of that macro has changed over time. I suspect it used to mean "whether job control was available", but now it's to decide whether to use setpgtp or setpgid. The part that puts emacs on its own foreground process group (narrow_foreground_group) does use setpgrp() (and calls tcsetpgrp()) but after a: #ifdef HAVE_SETPGID #if !defined (USG) || defined (BSD_PGRPS) #undef setpgrp #define setpgrp setpgid #endif #endif So in any case, it is calling setpgid() Just seems like a bug/overlook that narrow_foreground_group is not done on BSD and causes the problem you observe. -- Stephane
Re: SIGINT handling
2015-09-22 16:28:16 +0100, Stephane Chazelas: [...] > To add on that, the code was removed at some point altogether > http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=58eb6cf0f77547d29f4fddca922eb6f98c0ffb28 > in emacs-24.0.96 and then added back without the #ifdef > BSD_PGRPS > http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=322aea6ddf7ec7fd71410d98ec1de69f219aff3e > in emacs-24.2.90 [...] And here's the bug that prompted for reinserting that code, which is relevant to this discussion: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=12697 -- Stephane
local keyword hides return code of command substitution
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wall uname output: Linux idallen-oak 3.19.0-28-generic #30-Ubuntu SMP Mon Aug 31 15:52:51 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.3 Patch Level: 30 Release Status: release Description: Adding a "local" keyword to a variable assignment hides the return code of a command substitution. Same problem in both bash and dash shells. The keyword may be operating as described in the man page, but it is highly non-intuitive that adding it would do this. The work-around is to use "local" to declare the variable first, then do the command substitution assignment on another line and check the return code there. If the behaviour of "local" can't be changed, perhaps the man page could warn about this? Repeat-By: Run this: #!/bin/bash -u # Using "local" keyword hides return code of command substitution. # Same problem in both bash and dash shells. # -Ian! D. Allen - idal...@idallen.ca - www.idallen.com Myfunc () { foo=$( false ) echo "return code should be 1: $?" local bar=$( false ) echo "return code should be 1: $?" } Myfunc
Re: SIGINT handling
On 9/22/15 11:28 AM, Stephane Chazelas wrote: > 2015-09-22 15:18:32 +0100, Stephane Chazelas: >> 2015-09-22 09:41:35 -0400, Chet Ramey: >> [...] AFAICT emacs starts a new process group (and makes it the foreground process group). >>> >>> Maybe, if it's being run from an interactive shell or in a separate >>> X window. On the other hand, run this script with `dash': >> [...] >> >> It does that unconditionaly (since 94 at least), but that's >> under a #ifdef BSD_PGRPS in the emacs source. Strangely enough, >> that BSD_PGRPS is not defined anymore for freebsd or netbsd >> though it is for gnu-linux > [...] > > To add on that, the code was removed at some point altogether > http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=58eb6cf0f77547d29f4fddca922eb6f98c0ffb28 > in emacs-24.0.96 and then added back without the #ifdef > BSD_PGRPS > http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=322aea6ddf7ec7fd71410d98ec1de69f219aff3e > in emacs-24.2.90 > > So versions 24.0.96 to 24.2 must have been broken under > gnu-linux as well, and newer versions (24.2.90 and above) should > be OK including on FreeBSD|OS/X (so no need to report it as a > bug to the emacs maintainers). I don't use GNU emacs; it's not that big a deal. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
'[ --version' should give output, instead a bash error missing re: missing ']'
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wall uname output: Linux simeone-thinkpad 3.19.0-23-generic #24-Ubuntu SMP Tue Jul 7 18:52:55 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.3 Patch Level: 30 Release Status: release Description: According to the joint man page for '[' and 'test', '[ --version' and '[ --help' should give appropriate output, while 'test' should not. 'test' appears to behave correctly, but when running '[ --version' or '[ --help', the following error appers: bash: [: missing `]' It appears that whatever code is checking for syntax failed to take the two options that may be passed to '[' into account. Repeat-By: [ --help OUTPUT: bash: [: missing `]'
Re: SIGINT handling
2015-09-22 15:18:32 +0100, Stephane Chazelas: > 2015-09-22 09:41:35 -0400, Chet Ramey: > [...] > > > AFAICT emacs starts a new process group (and makes it the > > > foreground process group). > > > > Maybe, if it's being run from an interactive shell or in a separate > > X window. On the other hand, run this script with `dash': > [...] > > It does that unconditionaly (since 94 at least), but that's > under a #ifdef BSD_PGRPS in the emacs source. Strangely enough, > that BSD_PGRPS is not defined anymore for freebsd or netbsd > though it is for gnu-linux [...] To add on that, the code was removed at some point altogether http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=58eb6cf0f77547d29f4fddca922eb6f98c0ffb28 in emacs-24.0.96 and then added back without the #ifdef BSD_PGRPS http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=322aea6ddf7ec7fd71410d98ec1de69f219aff3e in emacs-24.2.90 So versions 24.0.96 to 24.2 must have been broken under gnu-linux as well, and newer versions (24.2.90 and above) should be OK including on FreeBSD|OS/X (so no need to report it as a bug to the emacs maintainers). -- Stephane
Re: local keyword hides return code of command substitution
On 09/22/2015 08:19 AM, idal...@idallen-fibe.dyndns.org wrote: > Description: > Adding a "local" keyword to a variable assignment hides the > return code of a command substitution. Same problem in both > bash and dash shells. > Not a bug. $() substition can only affect $? if it is executed in isolation, and not as an argument to some other command. 'local' is some other command. And while 'local' is not (yet) in POSIX, the behavior is the same for 'export', which IS specified by POSIX. For more details, read: http://austingroupbugs.net/view.php?id=960#c2777 in particular the section that says: > Note that, unless X was previously marked readonly, the value of $? after > > export X=$(false) > > will be 0 (because export successfully set X to the empty string) and that > execution continues, even if set -e is in effect. In order to detect command > substitution failures, a user must separate the assignment from the export, > as in > > X=$(false) > export X So, as you discovered, > The work-around is to use "local" to declare the variable first, > then do the command substitution assignment on another line and > check the return code there. That is not a workaround, so much as the correct behavior. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: '[ --version' should give output, instead a bash error missing re: missing ']'
On 09/22/2015 08:22 AM, Daniel Simeone wrote: > > Description: > According to the joint man page for '[' and 'test', '[ --version' > and '[ --help' should give appropriate output, while 'test' should not. You're probably reading the coreutils man page, rather than the bash man page. Bash has not (yet) implemented support for ANY --options to its builtins, although there has been talk on the list of doing so for future versions (especially since ksh has already done it). If you are executing the shell builtins instead of the coreutils versions, then the behavior you see is expected and not a bug. To see the behavior mentioned in the coreutils man page, be sure you run the coreutils version of [, as in: env [ --help or /bin/[ --help -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: local keyword hides return code of command substitution
2015-09-22 11:45:20 -0400, Greg Wooledge: > On Tue, Sep 22, 2015 at 10:19:56AM -0400, idal...@home.idallen.ca wrote: > > Description: > > Adding a "local" keyword to a variable assignment hides the > > return code of a command substitution. Same problem in both > > bash and dash shells. > > Yes, this is how it works. If you care about the return value of a > command used to initialize a local variable, you have to write it in > two steps: > > foo() { > local foo > foo=$(bar) || return > } [...] It also avoids problems with some other shells that support "local" as a normal command when one forgets to quote the $(command-subtitution) (where for instance local foo=$(echo bar baz) is like local foo=bar baz) Note that for "readonly", the assignment needs to be done first: foo=$(bar) || return readonly foo -- Stephane
Re: local keyword hides return code of command substitution
On Tue, Sep 22, 2015 at 10:19:56AM -0400, idal...@home.idallen.ca wrote: > Description: > Adding a "local" keyword to a variable assignment hides the > return code of a command substitution. Same problem in both > bash and dash shells. Yes, this is how it works. If you care about the return value of a command used to initialize a local variable, you have to write it in two steps: foo() { local foo foo=$(bar) || return } http://mywiki.wooledge.org/BashPitfalls has this and many more.
Re: '[ --version' should give output, instead a bash error missing re: missing ']'
On Tue, Sep 22, 2015 at 11:46:05AM -0500, Daniel Simeone wrote: > When I ran 'which [' it stated that the /usr/bin/[ was what was running, > and so I presumed it was in bash. which(1) is an external program, so it doesn't know about shell builtins. Use "type [" in bash intead. I'm quite fond of type -a: $ type -a [ [ is a shell builtin [ is /usr/bin/[
Re: '[ --version' should give output, instead a bash error missing re: missing ']'
You are correct: /usr/bin/\[ --help gives the desired output. When I ran 'which [' it stated that the /usr/bin/[ was what was running, and so I presumed it was in bash. Also, the error message says 'bash' So, all in all, a bit counfusing. Cheers, Daniel On 22 September 2015 at 10:39, Eric Blake wrote: > On 09/22/2015 08:22 AM, Daniel Simeone wrote: > > > > Description: > > According to the joint man page for '[' and 'test', '[ --version' > > and '[ --help' should give appropriate output, while 'test' should not. > > You're probably reading the coreutils man page, rather than the bash man > page. > > Bash has not (yet) implemented support for ANY --options to its > builtins, although there has been talk on the list of doing so for > future versions (especially since ksh has already done it). If you are > executing the shell builtins instead of the coreutils versions, then the > behavior you see is expected and not a bug. > > To see the behavior mentioned in the coreutils man page, be sure you run > the coreutils version of [, as in: > > env [ --help > or > /bin/[ --help > > -- > Eric Blake eblake redhat com+1-919-301-3266 > Libvirt virtualization library http://libvirt.org > > -- --Daniel Simeone PhD candidate, Candidat au doctorat, Université McGill University
Re: SIGINT handling
Greg Wooledge wrote: > Just for the record, ping is the *classic* example of an incorrectly > written application that traps SIGINT but doesn't kill itself with > SIGINT afterward. (This seems to be true on multiple systems -- at > the very least, HP-UX and Linux pings both suffer from it.) The command I run into the problem most with is 'rsync' in a loop. EXIT VALUES 0 Success ... 20 Received SIGUSR1 or SIGINT Which forces me to write such things this way. rsync ... rc=$? if [ $rc -eq 20 ]; then kill -INT $$ fi if [ $rc -ne 0 ]; then echo "Error: failed: ..." 1>&2 exit 1 fi Bob
Re: SIGINT handling
2015-09-22 12:04:45 -0600, Bob Proulx: > Greg Wooledge wrote: > > Just for the record, ping is the *classic* example of an incorrectly > > written application that traps SIGINT but doesn't kill itself with > > SIGINT afterward. (This seems to be true on multiple systems -- at > > the very least, HP-UX and Linux pings both suffer from it.) > > The command I run into the problem most with is 'rsync' in a loop. > > EXIT VALUES >0 Success > ... >20 Received SIGUSR1 or SIGINT > > Which forces me to write such things this way. > > rsync ... > rc=$? > if [ $rc -eq 20 ]; then > kill -INT $$ > fi > if [ $rc -ne 0 ]; then > echo "Error: failed: ..." 1>&2 > exit 1 > fi [...] Another (generic) work-around as mentioned at http://unix.stackexchange.com/a/230568 and here is to add: trap ' trap - INT kill -s INT "$$" ' INT That doesn't work properly if there are subshells though. That basically turns a WCE shell to WUE (for very simple scripts). For SIGQUIT, you'd probably want to disable core dumps as well: trap ' trap - QUIT ulimit -c 0 kill -s QUIT "$$" ' QUIT -- Stephane
Re: '[ --version' should give output, instead a bash error missing re: missing ']'
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 9/22/15 11:39 AM, Eric Blake wrote: > Bash has not (yet) implemented support for ANY --options to its > builtins Bash-4.4 has --help for all builtins except for a small set listed in the manual. - -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/ -BEGIN PGP SIGNATURE- Version: GnuPG v2 iEYEARECAAYFAlYBogIACgkQu1hp8GTqdKslKQCgkavag3njXvgJmzBgxuGqbDDx kJ0An1AigcthwISMnM86r0oBbOcSkyon =054h -END PGP SIGNATURE-