Reputation:
I'm curious to know if it makes a difference where the '&' operator is used in code when a process has input/output redirection to run a process in the background
What are the differences/are there any differences between these lines of code in terms of running the process in the background. If there are, how can I determine what the differences are going to be?
setsid python script.py < /dev/zero &> log.txt &
setsid python script.py < /dev/zero & > log.txt &
setsid python script.py < /dev/zero > log.txt &
setsid python script.py & < /dev/zero > log.txt
Upvotes: 7
Views: 6584
Reputation: 4752
It makes a difference. &
doubles as a command separator (just like ;
is command separator). What you're really doing in something like
setsid python script.py & < /dev/zero > log.txt
is running setsid python script.py
in the background and also running a "null" command (which comes after the &
) in the foreground (an additional &
at the end would run it in the background). That "null" command has its stdin redirected to /dev/zero and its stdout redirected to log.txt.
Also, &>
is a special operator in Bash. foo &>out
redirects both stdout and stderr to out while running foo
. It is not the same as foo & >out
, which runs foo
in the background also redirects the output of a null command to out.
(This support for "null" commands is why idioms like >foo
on a separate line, which you sometimes see in shell scripts, work for truncating a file.)
Upvotes: 0
Reputation: 361556
There are two uses of &
here. One is as a so-called control operator. Every command is terminated by a control operator such as &
, ;
or <newline>
. The difference between them is that ;
and <newline>
run the command in the foreground and &
does it in the background.
setsid python script.py < /dev/zero & > log.txt &
setsid python script.py & < /dev/zero > log.txt
These two lines, therefore, actually execute two commands each. The first is equivalent to the two commands:
setsid python script.py < /dev/zero &
> log.txt &
And the second is equivalent to:
setsid python script.py &
< /dev/zero > log.txt
If you're wondering, yes, > log.txt
and < /dev/zero > log.txt
are both legal commands. Lacking a command name, they simply process the redirections: each one creates an empty file called log.txt
.
setsid python script.py < /dev/zero &> log.txt &
This version with &>
is different from the one with & >
. &>
without a space is a special redirection operator in bash that redirects both stdout and stderr.
setsid python script.py < /dev/zero > log.txt &
This final version is similar to the previous one except it only redirects stdout to log.txt
. stderr continues to go to the terminal.
Upvotes: 7
Reputation: 6258
So the &
means different things, depending on the context.
In the first case:
setsid python script.py < /dev/zero &> log.txt &
the first &
is used together with a >
as &>
which means redirect both stderr and stdout. The last &
means run in the background
In the second case:
setsid python script.py < /dev/zero & > log.txt &
You have the first &
alone, which as above, means but the process in the background, in this case it's setsid python script.py < /dev/zero
, which gets put in the background. Then the rest of the line says, redirect no process to log.txt and background it, a bit of nonsense really.
In the third case:
setsid python script.py < /dev/zero > log.txt &
You have the &
at the end, so the whole thing gets put in the background, however your redirection only redirect stdout to log.txt, and not stderr, like in the first case.
In the final case:
setsid python script.py & < /dev/zero > log.txt
You put setsid python script.py
in the background, and redirect stdout of nothing into log.txt, and puts /dev/zero
into stdin of nothing.
Upvotes: 2