Coprocess

Concept: Bash Coprocesses

Purpose:

Bash coprocesses allow you to run a command in the background while maintaining two-way communication with the process via file descriptors. It’s particularly useful for tasks that require interaction between a script and a long-running process.

Key Idea:

The coprocess runs asynchronously, and your script can send input to it and read output from it via file descriptors, allowing efficient interaction without blocking the main script.

Use Case:

Imagine a scenario where you want to continuously send input to and receive output from a bc process (a basic calculator), which will process arithmetic expressions in the background. You can feed it expressions and receive results interactively.

Example:

# Display the current Bash PID using BASHPID
echo.log "Main Bash PID: $BASHPID"

# Start bc as a coprocess
coproc calc_process {
  echo.log "coproc BASHPID=$BASHPID"
  bc -l;
}

# Display the coprocess PID
echo.log "Coprocess PID: $!"

# Send arithmetic expressions to bc through the coprocess
echo "5 + 5" >&"${calc_process[1]}"
echo "10 / 2" >&"${calc_process[1]}"

# Read and display the output from bc
read result1 <&"${calc_process[0]}"
read result2 <&"${calc_process[0]}"

echo "Result of 5 + 5: $result1"
echo "Result of 10 / 2: $result2"

# Close the coprocess
kill "${calc_process_PID}"

Explanation:

  1. coproc calc_process { bc -l; }: This starts the bc calculator as a coprocess.

    • calc_process is an array that stores file descriptors for input (calc_process[1]) and output (calc_process[0]).
    • The bc -l command runs in the background and waits for input.
  2. echo "5 + 5" >&"${calc_process[1]}": Sends the arithmetic expression 5 + 5 to the bc process via its input file descriptor.

  3. read result1 <&"${calc_process[0]}": Reads the result of the calculation from the output file descriptor.

  4. kill "${calc_process_PID}": Terminates the coprocess once you are done.


How to Run:

  1. Save this script in a file, e.g., coprocess_example.sh.
  2. Run it:
    bash coprocess_example.sh
    

You’ll see:

stdout:
Result of 5 + 5: 10
Result of 10 / 2: 5.00000000000000000000
stderr
    Main Bash PID: 69935
    Coprocess PID: 69938
    coproc BASHPID=69938