user2563044
user2563044

Reputation:

Running a process in the background with input/output redirection

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

Answers (3)

Ulfalizer
Ulfalizer

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

John Kugelman
John Kugelman

Reputation: 361556

Control operator

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.

Redirection

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

jbr
jbr

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

Related Questions