Re: waiting for process substitutions

2024-07-26 Thread Chet Ramey

On 7/20/24 10:47 AM, Zachary Santer wrote:


I feel like that's most of the way there. I would argue 'wait -n'
without arguments should include the "last-executed process
substitution, if its process id is the same as $!," in the set of
running child processes it'll wait for, at least. Just for the sake of
consistency with 'wait' without arguments.


You could have looked at the actual commit, which contains the change log,
which says

- wait_for_any_job: check for any terminated procsubs as well as any
  terminated background jobs

wait_for_any_job is the function that backs `wait -n' without arguments.
Right now the code that restricts it to the last procsub is commented out.

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



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: 'wait -n' with and without id arguments

2024-07-26 Thread Chet Ramey

On 7/20/24 1:50 PM, Zachary Santer wrote:

Was "waiting for process substitutions"

For context:
$ git show -q origin/devel
commit 6c703092759ace29263ea96374e18412c59acc7f (origin/devel)
Author: Chet Ramey 
Date:   Thu Jul 18 16:48:17 2024 -0400

 job control cleanups; wait -n can return terminated jobs if
supplied pid arguments; wait -n can wait for process substitutions if
supplied pid arguments

On Thu, Jul 18, 2024 at 12:36 PM Chet Ramey  wrote:


On 7/14/24 8:40 PM, Zachary Santer wrote:


On Fri, Jul 5, 2024 at 2:38 PM Chet Ramey  wrote:


There is code tagged
for bash-5.4 that allows `wait -n' to look at these exited processes as
long as it's given an explicit set of pid arguments.


I agree with all the knowledgeable people here telling you that the
way 'wait -n' is still implemented in bash-5.3-alpha is obviously
wrong, but I also want to point out that the way you plan to change
its behavior in bash-5.4 still won't allow Greg's example below to
work reliably.


OK, but how would you do that? If a job has already terminated, and been
removed from the jobs list, how would you know that `wait -n' without pid
arguments should return it? There can be an arbitrary number of pids on
the list of saved pids and statuses -- the only way to clear it using wait
is to run `wait' without arguments.

You can say not to remove the job from the jobs list, which gets into the
same notification issues that originally started this discussion back in
January, and I have made a couple of changes in that area in response to
the original report that I think will address some of those. But once you
move the job from the jobs list to this list of saved pids, `wait' without
-n or pid arguments won't look for it any more (and will clear the list
when it completes). Why should `wait -n' without pid arguments do so?


'wait' without -n or pid arguments doesn't look in the list of saved
pids and statuses simply because it would serve no purpose for it to
do so. The return status will be 0, no matter how any child process
terminated, or even if there never was a child process. *

For 'wait -n', on the other hand:
"If the -n option is supplied, wait waits for a single job from the
list of ids or, if no ids are supplied, any job, to complete and
returns its exit status."
People are going to naturally expect 'wait -n' without pid arguments
to return immediately with the exit status of an already-terminated
child process, even if they don't provide id arguments. In order to do
so, 'wait -n' obviously has to look in the list of saved pids and
statuses.


I think the part you're missing is that processes get moved to this list
after the user has already been notified of their termination status.



If two jobs happen to finish simultaneously, the next call to wait -n
should reap one of them, and then the call after that should reap
the other.  That's how everyone wants it to work, as far as I've seen.

*Nobody* wants it to skip the job that happened to finish at the exact
same time as the first one, and then wait for a third job.  If that
happens in the loop above, you'll have only 4 jobs running instead of 5
from that point onward.


OK, if you can send me an example that shows bash doing the wrong thing
here, we can talk about it.



* Or in any case, 'wait' without arguments as the first command in a
script seemed to have a termination status of 0. But then the manual
says:
"If none of the supplied arguments is a child of the shell, or if no
arguments are supplied and the shell has no unwaited-for children, the
exit status is 127."


That describes the behavior of `wait -n' without arguments; it immediately
follows the sentence introducing the -n option.

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



OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: if source command.sh & set -e issue

2024-07-26 Thread Chet Ramey
On 7/24/24 1:53 PM, Mor Shalev via Bug reports for the GNU Bourne Again 
SHell wrote:



*if source command.sh ; then  echo passfi*


The man page says, about this scenario:

"The  shell  does  not  exit if the command that fails is
 part of the command list immediately following  a  while
 or  until  keyword, part of the test following the if or
 elif reserved words, part of any command executed  in  a
 &&  or || list except the command following the final &&
 or ||, any command in a pipeline but the last, or if the
 command's  return  value is being inverted with !.  If a
 compound command other than a subshell  returns  a  non-
 zero  status because a command failed while -e was being
 ignored, the shell does not exit."

The `set -e' is ignored because the `source' command is run in the test
portion of the `if' command.



Or, similarly:

source command.sh && echo pass


The set -e would be ignored because the source command is run as a non-
final part of an and-or list.


looking at the following:
morshalev@morsh:~/workspace1/soc/soc> cat script.sh
#!/bin/bash
(source command.sh) && echo pass


This is run in a subshell.



morshalev@morsh:~/workspace1/soc/soc> cat command.sh
#!/bin/bash
set -e
echo calling tool a
echo calling tool b
false
echo calling tool c
echo calling tool d


The man page says:

"If  a  compound  command or shell function executes in a
 context where -e is being ignored, none of the  commands
 executed  within  the  compound command or function body
 will be affected by the -e setting, even if  -e  is  set
 and  a  command returns a failure status.  If a compound
 command or shell function sets -e while executing  in  a
 context  where -e is ignored, that setting will not have
 any effect until the compound  command  or  the  command
 containing the function call completes."

So `set -e' doesn't take effect until the setting is no longer being
ignored. The contents of the sourced file are parsed as a compound
command.

The POSIX text is substantially similar, from

https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_26



*in 4.2 we get:*morshalev@morshalev:~/workspace16/soc2> ./script.sh
calling tool a
calling tool b

*in 4.4 we get:*
morshalev@morsh:~/workspace1/soc/soc> ./script.sh
calling tool a
calling tool b
calling tool c
calling tool d
pass


It changed in bash-4.3 as the result of

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

which codified the current requirements and

https://lists.gnu.org/archive/html/bug-bash/2012-12/msg00012.html

which specifically addressed this case.

There was extensive discussion on the posix shell mailing list in 2009
where we all hashed out the requirements and new behavior.

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



OpenPGP_signature.asc
Description: OpenPGP digital signature


a groff convenience for quoting man pages (was: if source command.sh & set -e issue)

2024-07-26 Thread G. Branden Robinson
Hi Chet,

At 2024-07-26T11:18:57-0400, Chet Ramey wrote:
> The man page says, about this scenario:
> 
> "The  shell  does  not  exit if the command that fails is
>  part of the command list immediately following  a  while
>  or  until  keyword, part of the test following the if or
>  elif reserved words, part of any command executed  in  a
>  &&  or || list except the command following the final &&
>  or ||, any command in a pipeline but the last, or if the
>  command's  return  value is being inverted with !.  If a
>  compound command other than a subshell  returns  a  non-
>  zero  status because a command failed while -e was being
>  ignored, the shell does not exit."

Like you, I frequently have reason to quote man pages to people.  The
adjustment of lines ends up looking a bit weird for people who read
email using a proportional font.[1]  If you're running groff 1.23.0
(released July 2023) on the machine you send email from, you can tell it
to suppress adjustment to both margins on the fly, without changing any
configuration files or defaults.

I have a shell function called "mailman"--merrily colliding with the
name of other software I don't personally use.

# As gman, but format for email.
mailman () {
local cmd=
case "$1" in
(-*)
opts="$opts $1"
shift
;;
esac

set -- $(man -w "$@")
cmd=$(zcat --force "$@" | \
  grog -Tutf8 -b -ww -P -cbou -rU0 -rLL=72n -rHY=0 -dAD=l \
   $opts)
zcat --force "$@" | $cmd | less
}

There are many conveniences packed into that function.  I'm happy to
elaborate further; follow-ups might be better sited on the groff list
than bug-bash.

Regards,
Branden

[1] ...such as those accursed with GMail, which has proudly refused to
support an option for rendering emails in monospace for 20+ years,
because everyone at Google is smarter than you


signature.asc
Description: PGP signature