3

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.

0

3 Answers 3

11

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.

5

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).

4
  • Very clever!... Commented Feb 6 at 15:53
  • 1
    Note that this may still be polling the file internally, though it will often be doing so in a way that is more efficient than a simple while loop in a shell script. Commented Feb 7 at 12:15
  • @AustinHemmelgarn I don't understand the comment. Of course it's "polling". The question was literally about file polling. And anyway, FWIW, at least in my tail implementation, it's still using the inotify mechanism for polling, it doesn't loop with sleep, if that's what you were trying to hint. But even if some implementations of tail do that, I don't see what's wrong with that.
    – aviro
    Commented Feb 7 at 12:30
  • 4
    @aviro The question was asking about alternatives to polling the file for changes. tail -f is definitely cleaner than doing it manually, so I would still consider this a good answer, but if someone is very specifically looking to not poll at all, it’s important to know that some implementations do in fact poll the file for changes. And, for the record, inotify isn’t polling, it’s event triggered even down at the lowest level in the kernel, just like essentially all other kernel-level APIs for this. Commented Feb 7 at 14:05
5

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.)

2
  • I was going to suggest inotify, but this works better for a bash script
    – Stewart
    Commented Feb 6 at 14:55
  • 1
    As a quick note, this approach is Linux-specific (there are equivalent interfaces on pretty much all other modern platforms, but they do not always have shell commands for interacting with them, and when they do it’s a different shell command). Commented Feb 7 at 12:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .