Reputation: 1997
Here's the code
#!/bin/bash
echo $$
cd $HOME && sleep 10 &
exit 0
now lets run sh test.sh
I got the result:
21936
which is the pid of the shell process I have ran.
and if I do ps -ef | grep test.sh
within 10 seconds which is the sleep time.
I got root 21937 1 0 12:41 pts/0 00:00:00 sh test.sh
Q1: It's supposed to be no test.sh
but just a sleep
process. Why there's still a test.sh
?
Q2: It seems like the test.sh
I grep out is not the same as the test.sh
I ran in the terminal, depend on the PID
. So how did the new test.sh
come out?
Hi, there's another case of this, if I change
cd $HOME && sleep 10 &
to
cd $HOME; sleep 10 &
It will not act the same way, the test.sh
will disappear right after executing sh test.sh
, there's only one sleep
process.
Upvotes: 1
Views: 68
Reputation: 49220
(OK, I'll go out on a limb and turn my guess/comment into an answer.)
Since the &&
-operator is essentially a shell-builtin, i.e. it needs to be processed by the shell, using it together with &
will create a child process for the/a shell and not the individual parts of it (or just the last part of it as it looks, you'd expected).
That even happens when all commands chained with &&
are external commands. For example, sleep 3 && sleep 5 &
will also create a sub shell process.
The ;
just separates individual commands, as if they'd been written on separate lines. So in this case only the command that preceeds the &
is forked ("send to the background").
(Of course, the original process that gets forked is always the shell - that is just the way how fork works - but in the second case, it is replaced with the executable of the actual command, sleep
in your example).
Upvotes: 2
Reputation: 7614
From Bash Reference Manual:
If a command is terminated by the control operator
&
, the shell executes the command asynchronously in a subshell.
That is to say, the parent shell process is forked (in spawning the subshell).
You can easily test this with the following snippet:
#!/usr/bin/env bash
print_subshell_level () { echo $BASH_SUBSHELL; }
printf "foreground: "
print_subshell_level
printf "background: "
print_subshell_level &
Output:
foreground: 0
background: 1
Upvotes: 1