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. 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.