zshprocess-substitution

while read loop with input from process substitution not exiting on break in zsh


Using zsh, I was trying to break the while loop after file move event, but break happens only after the second one. This only occurs when I try to execute script

#!/bin/zsh

while read changed; do
  echo $changed
  if [ $changed = MOVE_SELF ]; then
    echo "File was moved."
    break
  fi
done < <(inotifywait -m -e move_self --format "%e" $1)

echo "HI THERE"

in zsh. However, if I try the same code with #!/bin/bash it works as expected (loop breaks after the first event).


Solution

  • Behavior in zsh and bash is different. One of the possible solutions is to use & for command in process substitution. Diff:

    < done < <(inotifywait -m -e move_self --format "%e" $1)
    ---
    > done < <(inotifywait -m -e move_self --format "%e" $1 &)
    

    Looks like zsh is blocking waits for process substitution to execute again. Output of zsh -x after first execution of inotitywait without &:

    +script.sh:3> read -r changed
    +script.sh:3> inotifywait -m -e move_self --format %e file.lua
    Setting up watches.
    Watches established.
    +script.sh:4> echo MOVE_SELF
    MOVE_SELF
    +script.sh:5> [ MOVE_SELF '=' MOVE_SELF ']'
    +script.sh:6> echo 'File was moved.'
    File was moved.
    +script.sh:7> break