# Redirecting process substitutions

If you intend to use bash redirections and process substitutions together, they might look cryptic.

In this article I would like to debunk that confusion a little bit.

Let's start with

```
$ > >(echo fine) 2> >(echo error)
fine
```

Here the effect is the same as `echo error | echo fine`.

Next

```
$ > >(echo fine) 2> >(echo error >&2)
fine
error
```

Here the effect is the same as `echo fine; echo error >&2`. Because they are disjointed (none of them depend on the other), they are not piped. There is no recursion because `echo error >&2` just prints to terminal.

If we try the other way around

```
$ 2> >(echo error) > >(echo fine >&2)
error
```

This is the same as `{ echo fine >&2; } 3>&1 1>&2 2>&3 | echo error`.

If they are disjointed

```
$ 2> >(echo error) > >(echo fine)
error
fine
```

This is the same as `echo error; echo fine`.

What if we include a command to be run?

```
$ whoami > >(cat) 2> >(echo error)
error
logan
```

This is the same as `{ echo error & whoami; } | cat`. Well, more exactly can be thought of as `{ echo error & whoami 2>/dev/null; } | cat`.

Another example

```
$ whoami > >(sed 's/^/processed: /') 2> >(echo error)
processed: error
processed: logan
```

You could think of this as `{ echo error & whoami; } | sed 's/^/processed: /'` Or more exactly `{ echo error & whoami 2>/dev/null; } | sed 's/^/processed: /'`.

What if they are disjointed?

```
$ whoami > >(sed 's/^/processed: /') 2> >(echo error >&2)
error
processed: logan
```

This is the same as `echo error >&2; whoami 2>/dev/null | sed 's/^/processed: /'`.

Let's try with an invalid command.

```
$ BOB 2> >(cat) > >(echo hi >&2)
hi
BOB: command not found
```

This is the same as `{ echo hi >&2 & BOB >/dev/null; } 3>&1 1>&2 2>&3 | cat`.

What if we want to introduce a custom file descriptor?

```
$ whoami > >(sed 's/^/processed: /') 3>&1 2> >(echo error >&3)
processed: error
processed: logan
```

This is the same as `{ echo error & whoami 2>/dev/null; } | sed 's/^/processed: /'`. Here be careful that the order of redirections matter!

What if we mix valid and invalid commands in a substituted process?

```
$ > >(echo fine) 2> >(echo error >&2) 2> >(ls;whoami;echo bob >&2)
fine
error
```

Here we have preset stderr to print 'error' to terminal. So `ls;whoami` portion ends up printing 'fine' to terminal, and `echo bob >&2` portion ends up printing 'error'.

Also consider

```
$> >(echo fine) 2> >(ls;whoami;BOB)
fine
BOB: command not found
```
Here the difference is that stderr still points to the terminal. So the *BOB: command not found* error message is just sent to the terminal unaltered.

Also consider

```
$ BOB > >(echo fine) 2> >(echo error >&2) 2> >(ls;whoami;echo bob >&2)
fine
error
```

This has the same effect as `{ ls & whoami & } | echo fine; { echo bob >&2 & BOB >/dev/null; } 3>&1 1>&2 2>&3 | echo error >&2`. Here BOB is an invalid command.

Please note that the equivalences are for hints to aid understanding. They are not exact representations.
