Alternatives to file polling?

In the following code, I have to poll $tmp_input to continue executing the code because wezterm cli send-text is asynchronous. This makes sure that $tmp_input is ready.

tmp_input=$(mktemp ./tmp_input.XXXXXX)

echo "read input; echo $input > $tmp_input" | wezterm cli send-text --pane-id $bottom_pane_id --no-paste

while [ ! -s "$tmp_input" ]; do
    sleep 1
done

input_value=$(cat "$tmp_input")
rm "$tmp_input"

echo "Input was: $input_value" | wezterm cli send-text --pane-id $bottom_pane_id --no-paste

The code works, but I was wondering if there is another way of accomplishing the same result.

Asked By: wyc

||

Have you heard of inotifywait?
It sounds like what you want.

(I often use entr to execute on file changes – but I think you can achieve your goal with inotifywait.)

Answered By: Popup

You could create a named pipe with mkfifo instead, and read that. Reads will block until something has written to the pipe, no manual polling required. Something like:

tmp_input=$(mktemp -d ./tmp_input.XXXXXX)
mkfifo "$tmp_input/fifo"

echo "read input; echo $input > $tmp_input/fifo" | wezterm cli send-text --pane-id $bottom_pane_id --no-paste

input_value=$(cat "$tmp_input/fifo")
rm "$tmp_input/fifo"
rmdir "$tmp_input"

echo "Input was: $input_value" | wezterm cli send-text --pane-id $bottom_pane_id --no-paste

I switched to mktemp -d as a hopefully safer alternative to getting a name from mktemp and then using that name with mkfifo.

Answered By: muru

tail command has a -f/--follow flag which tells it to "output appended data as the file grows". Then you can use the head command to wait until the first line is written to the file.

input_value=$(tail -f "$tmp_input" | head -1)

Note it will only work if there’s a new line at the end of the first line (which is true in your case, since echo adds a new line to the end of the string by default).

Answered By: aviro