LinuxCommandLibrary

coproc

Run a command in the background

TLDR

Run a subshell asynchronously

$ coproc { [command1; command2; ...]; }
copy

Create a coprocess with a specific name
$ coproc [name] { [command1; command2; ...]; }
copy

Write to a specific coprocess stdin
$ echo "[input]" >&"$[{name[1]]}"
copy

Read from a specific coprocess stdout
$ read <&"$[{name[0]]}" [variable]
copy

Create a coprocess which repeatedly reads stdin and runs some commands on the input
$ coproc [name] { while read [line]; do [command1; command2; ...]; done }
copy

Create a coprocess which repeatedly reads stdin, runs a pipeline on the input, and writes the output to stdout
$ coproc [name] { while read [line]; do [echo "$line"] | [command1 | command2 | ...] | cat /dev/fd/0; done }
copy

Create and use a coprocess running bc
$ coproc BC { bc [[-l|--mathlib]]; }; echo "1/3" >&"${BC[1]}"; read <&"${BC[0]}" output; echo "$output"
copy

SYNOPSIS

coproc [-n name] [-P pid] {command ;}
coproc [-n name] [-P pid] command [arguments ...]

PARAMETERS

-n name
    Specifies the name for the coprocess array variable (default: COPROC). File descriptors accessed as ${name[0]} (read) and ${name[1]} (write).

-P pid
    Sets the parent process ID of the coprocess to pid, useful for process hierarchy management.

DESCRIPTION

coproc is a powerful Bash shell built-in command designed to create a coprocess, enabling bidirectional communication between the shell script and a background subprocess via pipes. When invoked, it launches the specified command asynchronously, establishing two file descriptors: [NAME][IN] for writing to the coprocess's stdin and [NAME][OUT] for reading from its stdout. By default, NAME is COPROC, but it can be customized.

This facilitates scenarios like processing streaming data, interacting with servers, or maintaining persistent background tasks without blocking the main script. For instance, you can read lines from the coprocess using read -u ${COPROC[0]} or write via echo 'data' >&${COPROC[1]}. The coprocess runs until the shell exits, the process is killed, or pipes close.

Unlike simple pipes (|), coproc provides named, reusable handles accessible anywhere in the script, making it ideal for complex workflows. It requires Bash 4.0+, supports compound commands in { } form for local variable scoping, and integrates seamlessly with Bash arrays for process management.

CAVEATS

Bash built-in only (Bash 4.0+); not portable to other shells. Coprocess terminates on shell exit or kill. Pipes are half-duplex; handle EOF carefully to avoid hangs. No direct stderr handling.

BASIC USAGE EXAMPLE

coproc SERVER { while read line; do echo "Echo: $line"; done; }
echo "Hello" &>&${SERVER[1]}
read reply <&${SERVER[0]}
echo $reply

CLEANUP

Use kill ${COPROC_PID} or coproc -P 0 to terminate. Check status with ${name_PIPE}.

HISTORY

Introduced in Bash 4.0 (February 2009) by Chet Ramey to enable efficient coprocessing, enhancing Bash's process control over prior pipe hacks. Enhanced in later versions with better error handling.

SEE ALSO

bash(1), exec(1), read(1), mkfifo(1)

Copied to clipboard