Question: This seems like a pretty trivial thing to do, but I'm very stuck.

To execute something in the background, use `&`:

```
>>> sleep 5 &
[1] 21763
>>> #hit enter
[1]+  Done                    sleep 5

```

But having a bashrc-sourced background script output job information is pretty frustrating, so you can do [this](https://stackoverflow.com/questions/7686989/running-bash-commands-in-the-background-without-printing-job-and-process-ids) to fix it:

```
>>> (sleep 5 &)

```

OK, so now I want to get the PID of `sleep` for `wait` or `kill`. Unfortunately its running in a subshell so the typical `$!` method doesn't work:

```
>>> echo $!
21763
>>> (sleep 5 &)
>>> echo $!
21763 #hasn't changed

```

So I thought, maybe I could get the subshell to print its PID in this way:

```
>>> sleep 5 & echo $!
[1] 21803 #annoying job-start message (stderr)
21803 #from the echo

```

But now when I throw that in the subshell no matter how I try to capture stdout of the subshell, it appears to block until `sleep` has finished.

```
>>> pid=$(sleep 5 & echo $!)

```

**How can I run something in the background, get its PID and stop it from printing job information and "`Done`"?**

Answer: 
Solution A
==========

When summoning the process, redirect the shell's stderr to `>/dev/null` for that summoning instance. We can do this by duplicating fd 2 so we could still use the duplicate fd for the process. We do all of these inside a block to make redirection temporary:

```
{ sleep 5 2>&3 & pid=$!; } 3>&2 2>/dev/null

```

Now to prevent the "Done" message from being shown later, we exclude the process from the job table and this is done with the `disown` command:

```
{ sleep 5 2>&3 & disown; pid=$!; } 3>&2 2>/dev/null

```

It's not necessary if job control is not enabled. Job control can be disabled with `set +m` or `shopt -u -o monitor`.

Solution B
==========

We can also use command substitution to summon the process. The only problem we had is that the process still hooks itself to the pipe created by `$()` that reads stdout but we can fix this by duplicating original stdout before it then using that file descriptor for the process:

```
{ pid=$( sleep 200s >&3 & echo $! ); } 3>&1

```

It may not be necessary if we redirect the process' output somewhere like `/dev/null`:

```
pid=$( sleep 200s >/dev/null & echo $! )

```

Similarly with process substitution:

```
{ read pid < <(sleep 200s >&3 & echo $!); } 3>&1

```

Some may say that redirection is not necessary for `process substitution` but the problem is that the process that may be accessing its `stdout` would die quickly. For example:

```
$ function x { for A in {1..100}; do echo "$A"; sleep 1s; done }
$ read pid < <(x & echo $!)
$ kill -s 0 "$pid" &>/dev/null && echo "Process active." || echo "Process died."
Process died.
$ read pid < <(x > /dev/null & echo $!)
$ kill -s 0 "$pid" &>/dev/null && echo "Process active." || echo "Process died."
Process active.

```

* Optionally you can just create a permanent duplicate fd with `exec 3>&1` so you can just have `pid=$( sleep 200s >&3 & echo $! )` on the next lines.
You can use `read` bulletin to capture output:

```
read -r pid < <(sleep 10 & echo $!)

```

Then:

```
ps -p $pid
  PID TTY           TIME CMD
78541 ttys001    0:00.00 sleep 10

```