Search code examples
bashgrepinotify

grep behaves strange in combination with inotifywait


I'm having a hard time understanding some sort of anomaly with grep return value.

As noted in the grep man page, the return value will be zero in case of a match and non-zero in case of no-match/error/etc.

In this code: (bash)

inotifywait -m ./logdir -e create -e moved_to |
  while read path action file; do
    if grep -a -q "String to match" "$path/$file"; then
      # do something  
    fi
  done

It returns non-zero when matched.

In this code: (bash)

search_file()
{
  if grep -a -q "String to match" "$1"; then
    # do something
  fi
}

inotifywait -m ./logdir -e create -e moved_to |
    while read path action file; do
      search_file "$path/$file"
    done

It returns zero when matched.

Can someone explain to me what is going on?

EDIT: Let me be clear once more: if I run the first code on a file that contains the string, the if statement is running. if i run the second code on the same file, the if statement fails and does not run.


Solution

  • I support @John1024's conjecture that he wrote as a comment.

    The "anomaly" is likely due to a slight timing difference between the two versions of your script. In case of a create event the file is initially empty, so grep will start scanning a partially written file. Calling grep through a function introduces a small delay, which increases the chances of the searched-for data to appear in the file by the time grep opens the file.

    The solution to this race condition depends on a couple of assumptions/requirements:

    • Can you assume that pre-existing files in the watched directory will not be modified?

    • Do you want to identify every new matching file as soon as possible, or you can afford delaying its processing until it is closed?