Bash does not end the loop even though the pipeline is damaged

Simple script:

while [ 1 ]; do
    cat pattern_file
done | socat - /dev/ttyS0

      

It creates a stream, a looped pattern included in a file, and sends it to the serial port via socat. The script also allows you to read data from the serial port. Unfortunately, when socat ends (eg killed) the loop hangs forever without an error message.
I want to avoid:

  • PTS
  • more scripts than one
  • reopening the serial port every pattern_file
+3


source to share


1 answer


The problem you are having is that in bash

(others may be different from the shell) the pipeline only finishes after all the commands in the pipeline have finished.

One solution is to use:

while [ 1 ]; do
    cat pattern_file || break
done | socat - /dev/ttyS0

      

If it socat

completes, the command cat

does not work when it is run. However, a simple failure of a command in a loop does not end the loop. By adding the command break

, we can guarantee that if cat

it fails, then the loop will end.

Another solution is to avoid pipelines altogether and use process replacement:



socat - /dev/ttyS0 < <(while true; do cat pattern_file; done)

      

Documentation

The problematic behavior of the pipeline is documented in man bash

:

The shell waits for all commands in the pipeline to complete before returning a value.

+2


source







All Articles