patternbashTip
coproc: running a persistent coprocess with bidirectional communication
Viewed 0 times
coproccoprocessbidirectionalIPCpersistent subprocessfile descriptorbackground
Error Messages
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"
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.