Dynamic allocation of file descriptors in Bash

Aug. 26, 2018, 1:30 p.m.

Since Bash version 4.1 it is possible to dynamically allocate file descriptors greater than 10. Useful for redirections

Example:

$ testfn () { 
    echo "This is STDOUT"
    echo "This is STDERR" 1>&2
}

$ (
    # Annotate output of the current subshell so it is visible
    # which file descriptor it comes from
    exec 2> >(sed -e "s/^/STDERR:/") > >(sed -e "s/^/STDOUT:/")

    # Unmodified output
    testfn

    # The folowing command will swap STDOUT and STDERR from testfn()
    { testfn 2>&${stderrfd} >&${stdoutfd}; } {stderrfd}>&1 {stdoutfd}>&2

    # Need to manually close the created descriptors after use
    exec {stderrfd}>&- {stdoutfd}>&-
)
STDERR:This is STDERR
STDERR:This is STDOUT
STDOUT:This is STDOUT
STDOUT:This is STDERR

Output is out of order because annotating processes run in async subshells