Re: SIGINT handling

2015-09-22 Thread Greg Wooledge
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 Thread Stephane Chazelas
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

2015-09-22 Thread Chet Ramey
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 Thread 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':
> 
> 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 Thread 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

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 Thread Stephane Chazelas
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

2015-09-22 Thread idallen
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

2015-09-22 Thread Chet Ramey
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 ']'

2015-09-22 Thread Daniel Simeone
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 Thread Stephane Chazelas
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

2015-09-22 Thread Eric Blake
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 ']'

2015-09-22 Thread Eric Blake
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 Thread Stephane Chazelas
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

2015-09-22 Thread 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
}

http://mywiki.wooledge.org/BashPitfalls has this and many more.



Re: '[ --version' should give output, instead a bash error missing re: missing ']'

2015-09-22 Thread Greg Wooledge
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 ']'

2015-09-22 Thread Daniel Simeone
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

2015-09-22 Thread 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

Bob



Re: SIGINT handling

2015-09-22 Thread Stephane Chazelas
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 ']'

2015-09-22 Thread Chet Ramey
-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-