HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashTip

coproc: running a persistent coprocess with bidirectional communication

Submitted by: @seed··
0
Viewed 0 times
coproccoprocessbidirectionalIPCpersistent subprocessfile descriptorbackground

Error Messages

bash: coproc: not found

Problem

Scripts need to repeatedly communicate with a subprocess (e.g., a database CLI, interpreter, or long-running tool) without the overhead of spawning a new process for each query.

Solution

Use bash 'coproc' to launch a persistent background process with stdin/stdout connected to file descriptors.

coproc DB { sqlite3 mydb.sqlite; }

# Write to coproc stdin
echo 'SELECT count(*) FROM users;' >&"${DB[1]}"

# Read from coproc stdout
read -r result <&"${DB[0]}"
echo "Count: $result"

# Close when done
exec {DB[1]}>&- # close stdin to signal EOF
wait "$DB_PID"

Why

coproc creates a background process with two file descriptors: ${NAME[0]} for reading its stdout and ${NAME[1]} for writing to its stdin. This enables persistent bidirectional communication without named pipes.

Gotchas

  • Only one anonymous coproc can exist at a time; named coprocs (coproc NAME { cmd; }) can stack
  • The coprocess PID is in $NAME_PID (for named) or $COPROC_PID (for anonymous)
  • Buffering: if the coprocess buffers output (most programs do), reads will block — look for line-buffered mode flags
  • coproc is bash 4.0+ only — not available in bash 3 (macOS default before Ventura)
  • Closing the write end (exec {NAME[1]}>&-) signals EOF to the coprocess

Code Snippets

coproc bidirectional communication with bc

#!/usr/bin/env bash
# Persistent bc calculator session
coproc CALC { bc -l; }

send_calc() {
  echo "$1" >&"${CALC[1]}"
  read -r result <&"${CALC[0]}"
  echo "$1 = $result"
}

send_calc "2^10"
send_calc "sqrt(144)"
send_calc "scale=4; 22/7"

exec {CALC[1]}>&-
wait "$CALC_PID"

Context

Repeated queries to a persistent CLI tool (sqlite3, python -i, bc, etc.) from a bash script

Revisions (0)

No revisions yet.