bashpipebufferbarrierbash-trap

Bash script pipe barrier


My current script looks like this:

#!/bin/bash

trap flush_buffer SIGUSR1

flush_buffer() {
    echo "flushing buffer" >&2
    [ -n "$buffer" ] && echo -e "$buffer"
    buffer=""
}

trap exit_script INT TERM

exit_script() {
    echo "script shutting down" >&2
    flush_buffer()
}

while read -r line; do
    [ -z "$buffer" ] && buffer="$line" || buffer="$buffer\n$line"
done

There are test cases like this:

$(echo "ad-hoc run the script" | ./pipe-barrier.sh 2> /dev/null) == "ad-hoc run the script"

But this is not even working too.

And does this code behave the following cases correctly?

Thanks for help :)

UPDATE

#!/bin/bash

trap flush_buffer USR1

flush_buffer() {
    echo "flushing buffer" >&2
    [ -n "$buffer" ] && echo -e "$buffer"
    buffer=""
}

trap exit_script EXIT

exit_script() {
    echo "script shutting down" >&2
    flush_buffer
    exit 0
}

while read -r line; do
    [ -z "$buffer" ] && buffer="$line" || buffer="$buffer\n$line"
done

Solution

  • There are couple problems in your script... dropping 2> /dev/null from your test wold be provide you with useful hint to spot:

        flush_buffer()
    

    Function call should be

        flush_buffer
    

    Also, the other problem is. When you run out of input, you just exit the script, but never flush your buffer... either add flush_buffer past the while loop to call it in that case... or also set use it as a handler setting trap on EXIT.


    I can just as well update this I reckon: Your update... there is still one other problem... if you handle the INT and TERM signals, you return control back to where the trap was set off (very likely the while loop): You want to explicitly exit from exit_script.

    Also as per docs:

    A trap on EXIT is executed before the shell terminates.

    So... you really only set a trap on EXIT... otherwise in case of being tripped by SIGINT or SIGTERM, you'd call it (and flush) twice. Once to on the two signals... and then second time with an empty buffer on exiting.