[Top][All Lists]

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

Re: 'wait' in command group in pipeline fails to recognize child process

From: Martin Jambon
Subject: Re: 'wait' in command group in pipeline fails to recognize child process
Date: Tue, 22 Jun 2021 15:32:14 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1

On 6/22/21 1:37 PM, Greg Wooledge wrote:
On Tue, Jun 22, 2021 at 01:12:10PM -0700, Martin Jambon wrote:
On 6/22/21 4:31 AM, Greg Wooledge wrote:
A pipeline creates two or more subshells, one for each command in the
pipeline.  Therefore, your wait command is running in a different
process than the one which created the sleep background job.

The curly braces are irrelevant here.

unicorn:~$ sleep 1 & wait "$!"|cat
[1] 1290127
bash: wait: pid 1290127 is not a child of this shell

Thank you! Now I know that a subshell is not a shell, $$ being the process
ID of the shell, not of the subshell.

It's a forked child process of bash, and as such, it's still a shell.
Specifically, it's bash.

There's some formal definition that you can ignore.  The real definition
of a subshell is "the direct result of a fork()".  It inherits all of
the shell variables, functions, aliases, and so on that the parent
shell process had at the time of the fork.

This is different from a direct call to "bash", which would not inherit
shell variables and so on -- only environment variables.

Great, then I would change the documentation of '$$'. Currently it says this:

($$) Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the invoking shell, not the subshell.

This first mentions just "the shell". I suggest calling it the "root shell" instead, i.e. the process where "exec bash" took place. I would also mention pipelines here, since these are more commonly used than () subshells. I don't know if there are other ways of creating subshells. If that's all, I think it would be valuable to mention those two cases rather than just one.

Well, I suppose "root shell" could be misunderstood as a shell run by the 'root' user but this doesn't make much sense in this context. I can't find a better name. Here's how we might change the description of '$$':

($$) Expands to the process ID of the root shell. In a pipeline or in a () subshell, it expands to the process ID of the root shell, not the subshell.

I also changed "invoking shell" to "root shell" because the invoking shell or parent shell is not necessarily the same as the root shell e.g.

$ echo $$; (echo $$; (echo $$))

In the pipeline, there are two subshells created.  One of them runs
the command wait "$!", and the other runs the command cat.

The special parameter $! is inherited from the parent shell, and contains
the PID of the sleep process that the parent shell created.  But the
child subshell can't wait for that process, because it belongs to someone
else.  Hence the error message.

👍 Yup. I think the error message is clear. No complaint about that.

reply via email to

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