Running bash commands in the background without printing job and process ids

BashBash Completion

Bash Problem Overview


To run a process in the background in bash is fairly easy.

$ echo "Hello I'm a background task" &
[1] 2076
Hello I'm a background task
[1]+  Done                    echo "Hello I'm a background task"

However the output is verbose. On the first line is printed the job id and process id of the background task, then we have the output of the command, finally we have the job id, its status and the command which triggered the job.

Is there a way to suppress the output of running a background task such that the output looks exactly as it would without the ampersand at the end? I.e:

$ echo "Hello I'm a background task" &
Hello I'm a background task

The reason I ask is that I want to run a background process as part of a tab-completion command so the output of that command must be uninterrupted to make any sense.

Bash Solutions


Solution 1 - Bash

Not related to completion, but you could supress that output by putting the call in a subshell:

(echo "Hello I'm a background task" &)

Solution 2 - Bash

Building off of @shellter's answer, this worked for me:

tyler@Tyler-Linux:~$ { echo "Hello I'm a background task" & disown; } 2>/dev/null; sleep .1;
Hello I'm a background task
tyler@Tyler-Linux:~$

I don't know the reasoning behind this, but I remembered from an old post that disown prevents bash from outputting the process ids.

Solution 3 - Bash

In some newer versions of bash and in ksh93 you can surround it with a sub-shell or process group (i.e. { ... }).

/home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null
Hello I'm a background task
/home/shellter $

Solution 4 - Bash

Based on this answer, I came up with the more concise and correct:

silent_background() {
    { 2>&3 "$@"& } 3>&2 2>/dev/null
    disown &>/dev/null  # Prevent whine if job has already completed
}
silent_background date

Solution 5 - Bash

Building on the above answer, if you need to allow stderr to come through from the command:

f() { echo "Hello I'm a background task" >&2; }
{ f 2>&3 &} 3>&2 2>/dev/null

Solution 6 - Bash

Try:

user@host:~$ read < <( echo "Hello I'm a background task" & echo $! )
user@host:~$ echo $REPLY
28677

And you have hidden both the output and the PID. Note that you can still retrieve the PID from $REPLY

Solution 7 - Bash

Sorry for the response to an old post, but I figure this is useful to others, and it's the first response on Google.

I was having an issue with this method (subshells) and using 'wait'. However, as I was running it inside a function, I was able to do this:

function a {
    echo "I'm background task $1"
    sleep 5
}

function b {
    for i in {1..10}; do
        a $i &
    done
    wait
} 2>/dev/null

And when I run it:

$ b
I'm background task 1
I'm background task 3
I'm background task 2
I'm background task 4
I'm background task 6
I'm background task 7
I'm background task 5
I'm background task 9
I'm background task 8
I'm background task 10

And there's a delay of 5 seconds before I get my prompt back.

Solution 8 - Bash

The subshell solution works, but I also wanted to be able to wait on the background jobs (and not have the "Done" message at the end). $! from a subshell is not "waitable" in the current interactive shell. The only solution that worked for me was to use my own wait function, which is very simple:

myWait() {
  while true; do
    sleep 1; STOP=1
    for p in $*; do
	  ps -p $p >/dev/null && STOP=0 && break
	done
	((STOP==1)) && return 0
  done
}

i=0
((i++)); p[$i]=$(do_whatever1 & echo $!)
((i++)); p[$i]=$(do_whatever2 & echo $!)
..
myWait ${p[*]}

Easy enough.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex SpurlingView Question on Stackoverflow
Solution 1 - BashDimitre RadoulovView Answer on Stackoverflow
Solution 2 - BashTyzoidView Answer on Stackoverflow
Solution 3 - BashshellterView Answer on Stackoverflow
Solution 4 - BashTom HaleView Answer on Stackoverflow
Solution 5 - BashpajamianView Answer on Stackoverflow
Solution 6 - Bashmark_infiniteView Answer on Stackoverflow
Solution 7 - BashThe TomahawkView Answer on Stackoverflow
Solution 8 - BashExpertNoob1View Answer on Stackoverflow