1

I am trying to run the following function

foo () {
    sleep 1
    echo "outside inotify"
    (inotifywait . -e create |
    while read path action file; do
        echo "test"
        sleep 1
    done)
    echo "end"
}

Until inotifywait it runs correctly; I see:

>> foo
outside inotify
Setting up watches.
Watches established.

However as soon as I create a file, I get

>>> fooo
outside inotify
Setting up watches.
Watches established.
test
foo:6: command not found: sleep
end

Any idea why? Plus do I need to spawn the subprocess ( ) around inotifywait? what are the benefits?

thank you.

Edit I realized I am running on zsh

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
manolius
  • 395
  • 3
  • 15
  • Is `sleep` a loadable builtin by any chance? Run `type sleep` to find out. – oguz ismail Apr 10 '20 at 15:57
  • 1
    Thank you oguz. `type sleep` returns "sleep is /bin/sleep" – manolius Apr 10 '20 at 19:10
  • That's really weird. If you ever find out the problem please let me know – oguz ismail Apr 10 '20 at 19:13
  • I just realized I am running on a machine with zsh. I tested with bash and works correctly – manolius Apr 10 '20 at 22:30
  • Re: the subprocess, pipelines *always* start one. If you didn't make it explicit, you'd still have one anyhow. Having it be explicit in the code makes it clear to readers that variables they set in the `while read` loop won't be accessible anywhere else. – Charles Duffy Apr 10 '20 at 23:33

1 Answers1

3

The read path is messing you up, because unlike POSIX-compliant shells -- which guarantee that only modification to variables with all-uppercase names can have unwanted side effects on the shell itself -- zsh also has special-cased behavior for several lower-case names, including path.

In particular, zsh presents path as an array corresponding to the values in PATH. Assigning a string to this array will overwrite your PATH as well.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441