0

I am using:

inotifywait -m -q -e close_write --format %f . | while IFS= read -r file; do
cp -p "$file" /path/to/other/directory
done

to monitor a folder for file completion, then moving it to another folder.

Files are made in pairs but at separate times, ie File1_001.txt is made at 3pm, File1_002.txt is made at 9pm. I want to monitor for the completion of BOTH files, then launch a script.

script.sh File1_001.txt File1_002.txt

So I need to have another inotifywait command or a different utility, that can also identify that both files are present and completed, then start the script.

Does anyone know how to solve this problem?

  • 1
    I don't understand enough of your requirements or what your challenge is; It seems to me that you could just launch your wait loop twice, once for each file. That said, [this answer](http://stackoverflow.com/a/10958125/1072112) might provide you with an alternate strategy. Note that with that answer *and* with your script excerpt in your question, you may experience failures if filenames have non-standard characters like spaces or newlines or other control characters in them. – ghoti Mar 16 '16 at 19:03
  • What @ghoti said; your requirements are way to vague. – tink Mar 16 '16 at 19:43
  • @ghoti Thanks, I have updated my question to try and be more clear. I need to wait for both files that are separated by a delimiter to be closed, then pass both file names to a new script. Meaning, File1_001.txt and File1_002.txt should be passed, even if File2_001.txt finishes before File1_002.txt. – Jared Taylor Mar 16 '16 at 19:58
  • 1
    If they are created 6 hours apart, latency can't be an issue, so if you checked the 2 files every 10 minutes in `cron` and ran your script if both were present, wouldn't that be good enough? You must have some knowledge of the creating process such that you know it writes once a minute or somesuch, so you could know it had finished writing if the modification time was more than 2 minutes ago. – Mark Setchell Mar 16 '16 at 22:18

1 Answers1

1

I found a Linux box with inotifywait installed on it, so now I understand what it does and how it works. :)

Is this what you need?

#!/bin/bash

if [ "$1" = "-v" ]; then
        Verbose=true
        shift
else
        Verbose=false
fi

file1="$1"
file2="$2"

$Verbose && printf 'Waiting for %s and %s.\n' "$file1" "$file2"

got1=false
got2=false
while read thisfile; do
        $Verbose && printf ">> $thisfile"
        case "$thisfile" in
                $file1) got1=true; $Verbose && printf "... it's a match!" ;;
                $file2) got2=true; $Verbose && printf "... it's a match!" ;;
        esac
        $Verbose && printf '\n'
        if $got1 && $got2; then
                $Verbose && printf 'Saw both files.\n'
                break
        fi
done < <(inotifywait -m -q -e close_write --format %f .)

This runs a single inotifywait but parses its output in a loop that exits when both files on the command line ($1 and $2) are seen to have been updated.

Note that if one file is closed and then later is reopened while the second file is closed, this script obviously will not detect the open file. But that may not be a concern in your use case.

Note that there are many ways of building a solution -- I've shown you only one.

ghoti
  • 45,319
  • 8
  • 65
  • 104