Xu Wang
Xu Wang

Reputation: 10607

Use inotifywait -m in script without creating extra process?

I am not sure this is possible, but I've often thought that and some solutions have amazed me. Is it possible to create the equivalent of the following script without creating two processes (in this case, it is clear two processes are created because there is a pipe):

#!/bin/bash

EVENTS="CREATE,CLOSE_WRITE,DELETE,MODIFY,MOVED_FROM,MOVED_TO"
inotifywait -e "$EVENTS" -m -r ~/Desktop/testing | \
  while true; do
    read TMP
    echo "${TMP}" >> ~/Desktop/eventlog
  done

Note that inside the while loop I do want to have access to the event.

It seems to me that a pipe is necessary because we need to write with one process and read from another. But maybe there exists a trick?

Upvotes: 0

Views: 733

Answers (2)

chepner
chepner

Reputation: 532408

In bash 4.2, you can set the lastpipe option to allow the while loop to run in the current shell instead of a separate process.

shopt -s lastpipe
inotifywait -e "$EVENTS" -m -r ~/Desktop/testing |
  while true; do
    read TMP
    echo "${TMP}" >> ~/Desktop/eventlog
  done

(You don't need an explicit line continuation after the |, since bash knows that a line cannot end with that character.)

Upvotes: 2

nhed
nhed

Reputation: 5999

Is it correct to assume that you are looking to avoid a secondary script so that variables modified in the for loop dont lose their value once the loop is done?

In that case you can just swap and so something like

while read TMP; do
  echo "${TMP}" >> ~/Desktop/eventlog
done < <(inotifywait -e "$EVENTS" -m -r ~/Desktop/testing)

but if you are concerned about flexibility of your code flow you can redirect to a file handle and then read from that handle whenever comment below if you want me to fish out en example

if it's something else - please add detail as to what you are actually looking to do

Upvotes: 1

Related Questions