42

For example, when I type ping 8.8.8.8 &, why can we see ping process working? And when I type find / -name '*test*' & , it's also seen on monitor.

Why is that? Is it not really in background?

3 Answers 3

59

The & directs the shell to run the command in the background, i.e, it is forked and run in a separate sub-shell, as a job, asynchronously.

Note that when you put & the output - both stdout and stderr - will still be printed onto the screen. If you do not want to see any output on the screen, redirect both stdout and stderr to a file by:

myscript > ~/myscript.log 2>&1 &

Usually you may want to discard the stderr by redirecting it to /dev/null if you are not worried about analyzing errors later.

You can also even run commands/scripts at the same time, in separate sub-shells. For eg;

./script1 & ./script2 & ./script3 & 

A background job can be brought back to the command line before it finishes with the command:

fg <job-number>

The job-number can be obtained by running

jobs
6
  • Good answer. You could include that one can also use /dev/null as a file to redirect terminal output if one wants to discard the output instead of saving it somewhere. And am I right that 2>&1 redirects stderr to stdout? Maybe you want to clarify that too... Thanks.
    – Byte Commander
    Aug 18, 2015 at 9:44
  • @ByteCommander Thanks :) edited, hope it is clear now. Yes, you are right, 2>&1 redirects stderr to stdout.
    – Ron
    Aug 18, 2015 at 10:27
  • 3
    I think it would be worth mentioning that stty tostop will cause background jobs to be suspended if they try to write to the terminal.
    – kasperd
    Aug 18, 2015 at 11:12
  • cmd_with_params >/dev/null 2>/dev/null &
    – tgkprog
    May 22, 2017 at 16:11
  • The only downside of doing that is that the order of the outputs to stdout and stderr can get mixed up in the log file.
    – matthieu
    Apr 7, 2019 at 10:44
12

When you use &, the process is running in background. But its standard output is still the terminal.

In fact, you may run ping 8.8.8.8 & and find / -name '*test*' & at the same time (resulting in a mixed output), but you may not run ping 8.8.8.8 and find / -name '*test*' at the same time on the same shell.

If you don't want to see anything, use something like ping 8.8.8.8 &> /dev/null &.


Additionally, you may want to learn about nohup and disown.

2
  • 1
    disown doesn't prevent output from being printed to the terminal.
    – Ruslan
    Aug 18, 2015 at 11:53
  • 1
    @Ruslan: no, but it removes the job from the shell. Which may (or may not) be something the OP may be interested in. Aug 18, 2015 at 11:55
1

I wanted to try and answer specifically the why part:

Why is that?

POSIX implementation of job control, choose to attach STDOUT,STDERR to the parent terminal[1]. I suspect this was the default choice historically perhaps because there used to be just one physical terminal and no emulators back in the day, and so the terminal was the only choice where all jobs could write output to(?)

And STDOUT/ERR seems to be rather hard to get back if you have created the the terminal without a program like screen and your terminal and the shell in it is in-accessible or susceptible to die if you closed your SSH: https://superuser.com/questions/50058/after-the-fact-remote-nohup-with-tcsh/50077#50077 Though as the answer there indicates, it could be done by attaching gdb if the parent shell has disowned the process. It's also an important reason why Terminal Emulators are so useful because interactive processes can't really generally survive without each one getting its own terminal..

[1] https://www.gnu.org/software/libc/manual/html_node/Access-to-the-Terminal.html

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .