Why can I see the output of background processes?

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?

4 Answers

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

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

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: 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]

The modern and easy to use approach that allows managing multiple processes and has a nice terminal UI is hapless utility.

Install with pip install hapless (or python3 -m pip install hapless) and just run

$ hap run my-command # e.g. hap run python my_long_running_script.py
$ hap status # check all the launched processes
$ hap logs 4 # output logs for you 4th background process
$ hap logs -f 2 # continuously stream logs for the 2nd process

You don't need to set any redirects and can inspect status/output at any time. See docs for more info.

ui

NOTE: I'm the author of this package.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like