19

I have trouble understanding my situation and Google was not very helpful so far.

I started a bash background job:

ping google.com &

First I get the process ID, than Bash prints stdout to screen.

user@host:~$ ping google.com &
[1] 14004
user@host:~$ PING google.com (173.194.44.66) 56(84) bytes of data.
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=1 ttl=54 time=26.3 ms
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=2 ttl=54 time=27.4 ms
64 bytes from ham02s14-in-f2.1e100.net (173.194.44.66): icmp_seq=3 ttl=54 time=29.2 ms
...

This contradicts everything I read today. I have a standard Debian Jessie setup running GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu).

Can anyone explain this to me? Thanks.

2 Answers 2

22

By default, at least for POSIX compliant systems, running a command in background, with &, only detaches stdin, so you'll be able to run other commands. stdout and stderr are still attached to the parent shell.

If you don't want to see stdout and/or stderr you can just redirect them to a file or /dev/null:

command &>log.txt &                #stdout and stderr to log.txt
command 1>/dev/null &               #stdout to /dev/null, stderr still attached to shell
command 1>output.log 2>error.log &  #stdout to output.log, stderr to error.log
3
  • On MacOSX this does not work. Mar 13, 2018 at 9:33
  • 1
    @OgierSchelvis: Of course it does. Nov 27, 2018 at 23:27
  • 1
    Is there a way to reattach stdin in this case?
    – alecov
    Jan 16, 2019 at 4:51
10

Whether stdout of a background process is shown on the terminal is up to you. You can change the behavior with the stty utility.

Example

The default allows a background process to write to terminal:

$ echo Hello &
[1] 25850
Hello
$

That behavior can be changed with the stty command:

$ stty tostop
$ echo Hello &
[2] 25873

[2]+  Stopped                 echo Hello
$ 

With tostop specified, the background process is stopped when it attempts to write to stdout. If you want to allow it to continue, you can bring it back to the foreground:

$ fg
echo Hello
Hello
$

To switch back, run stty -tostop. After this is run, new background jobs that are created will be allowed to write to stdout. (Existing jobs will not be affected.)

Documentation

man stty explains the tostop option as follows:

* [-]tostop
stop background jobs that try to write to the terminal

The leading * above is used by the man page to identify this option as non-POSIX.

You must log in to answer this question.

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