bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Logical expressions and job control


From: Chet Ramey
Subject: Re: Logical expressions and job control
Date: Mon, 13 Feb 2023 17:25:46 -0500
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.7.1

On 2/10/23 1:10 PM, Godmar Back wrote:
Hi,

the students in my Systems course are currently working on their shell
assignment and of course are giving bash a spin to compare features. One
student pointed out that logical expressions such as `a` && `b` in bash
don't seem to work when `a` is stopped and resumed.

I suppose it all depends on what you mean by `work' (and I can assure you
there are different interpretations here). If you send `a' a SIGTSTP, it
returns control to its parent and modifies $?.

For example:

$ sleep 10
^Z
[1]+  Stopped                 sleep 10
$ echo $?
146

So if you use $? as the determining factor for whether or not to execute
`b', you're obviously not going to run it.

Just about every shell except ksh93 does this. It's the collision of job
control, which is process (group) based, and an AND-OR list that consists
of multiple commands that can spawn multiple processes.


For instance:

gback@lat2022:~$ sleep 10 && echo yes
^Z
[1]+  Stopped                 sleep 10
gback@lat2022:~$ fg
sleep 10
gback@lat2022:~$

`echo yes` appears to not execute, despite the fact that `sleep` exited
with status 0/success.
I verified with strace that `sleep` does not change its exit status in
response to being stopped and resumed.

Testing other shells, I found that csh, fish, and zsh have the same
behavior as bash, but ksh will execute `echo` and print `yes` in this
situation.

You can add yash, dash, mksh, and the BSD shells (dash siblings) to the
`works like bash' list.

When run in a subshell via (...) job control works as expected.

Because you force the command to be executed in a subshell that is stopped
as a unit when you send it SIGTSTP. There are various ways you can do this:

{ sleep 10 && echo yes; } & fg
sleep 10 && echo yes & fg

and so on.

I tried to find a relevant passage in the 2008 POSIX standard (the version
I had handy), but it doesn't seem to address this situation specifically.
Based on what it says, I would expect it to run the next command solely on
the exit status of the first command, but bash somehow doesn't appear to do
that when the first command was stopped and continued.

POSIX finally tackled the issue in

https://www.austingroupbugs.net/view.php?id=1254

and leaves this part explicitly unspecified.

What's the rationale for bash's behavior in this case and is this something
that should be changed?

The cause and rationale should be clear from the explanation above. Pretty
much every shell but ksh behaves like bash, so this is probably going to
stay as-is.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://tiswww.cwru.edu/~chet/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]