2016-09-12 3 views
0

Ich habe das folgende Skript (Shell-Skript läuft auf OEL5.6), die derzeit über Cron geplant ist, um Dateien aus bestimmten Verzeichnissen (in einer Datenbanktabelle angegeben) auszuwählen und ein Verarbeitungsskript für sie aufzurufen auf einem Verzeichnis & Dateimaske Basis. Das Skript funktioniert im Moment gut, aber mit dieser Implementierung, wenn ein Ordner eine große Menge an zu verarbeitenden Dateien hat, selbst wenn alle anderen Ordner vollständig sind, wird das Skript erst dann beendet, wenn Dateien in den anderen Ordnern landen bis zum nächsten Lauf abgeholt werden. Ich würde gerne einen ähnlichen Ansatz verwenden, aber dafür, dass Ordner ständig nach neuen Dateien durchsucht werden, anstatt nacheinander durch alle Ordner zu laufen und dann zu beenden, so dass es als mehr Daemon im Hintergrund läuft. Irgendwelche Ideen, anstatt diese in eine while true Schleife einzuwickeln? Ich habe ein wenig Code aus diesem Beispiel herausgefiltert, um es kurz zu halten.Shell-Skript Dateibeobachter Parallelität

readonly HOME_DIR="$(cd $(dirname $0)/;echo $PWD)" 
export LOCK_DIR="/tmp/lock_folder" 

check_lock() { 
    # Try and create the $LOCK_DIR lock directory. Exit script if failure. 
    # Do some checks to make sure the script is actually running and hasn't just failed and left a lock dir. 
} 

main(){ 
    # Check to see if there's already an instance of the watcher running. 
    check_lock 

    # when the watcher script exits remove the lock directory for the next run 
    trap 'rm -r $LOCK_DIR;' EXIT 

    # Pull folder and file details into a csv file from the database -> $FEEDS_FILE 

    # Loop through all the files in given folders 
    while IFS="," read feed_name feed_directory file_mask 
    do 

     # Count the number of files to process using the directory and file mask 
     num_files=$(find $feed_directory/$file_mask -mmin +5 -type f 2> /dev/null | wc -l 2> /dev/null) 
     if [[ $num_files < 1 ]]; then 
      # There's no files older than 5 mins to pickup here. Move on to next folder. 
      continue 
     fi 

     # Files found! Try and create a new feed_name lock dir. This should always pass first loop. 
     if mkdir $LOCK_DIR/$feed_name 2>/dev/null; then 
      $HOME_DIR/another_script.sh "$feed_name" "$feed_directory" "$file_mask" & # Call some script to do processing. This script removes it's child lock dir when done. 
     else 
      log.sh "Watcher still running" f 
      continue 
     fi 

     # If the amount of processes running as indicated by child lock dirs present in $LOCK_DIR is greater than or equal to the max allowed then wait before re-trying another. 
     while [ $(find $LOCK_DIR -maxdepth 1 -type d -not -path $LOCK_DIR | wc -l) -ge 5 ]; do 
      sleep 10 
     done 

    done < $FEEDS_FILE 

    # Now all folders have been processed make sure that this script doesn't exit until all child scripts have completed (and removed their lock dirs). 
    while [ $(find $LOCK_DIR -type d | wc -l) -gt 1 ]; do 
     sleep 10 
    done 

    exit 0 
} 

main "[email protected]" 
+0

Was OS ist das? – redneb

+0

Das Betriebssystem ist OEL 5.6 –

Antwort

2

Eine Idee ist inotifywait von inotify-tools zu verwenden, um die Verzeichnisse für Änderungen zu überwachen. Dies ist effizienter, als die Verzeichnisse ständig nach Änderungen zu durchsuchen. So etwas wie das

inotifywait -m -r -e create,modify,move,delete /dir1 /dir2 | 
    while IFS= read -r event; do 
     # parse $event, act accordingly 
    done 
+0

Der aktuelle Prozess wird von einer Config-Tabelle, die wie folgt aussieht: Feed-Name, Verzeichnis, Dateimaske, .... Kann ich mit inotifywait diesen Ansatz nutzen? Für jedes Verzeichnis und jede Dateimaskenkombination werden verschiedene Parameter angewendet, die in meinem Beispiel aus der Datenbanktabelle an die Datei "another_script.sh" übergeben werden. –

+0

'inotifywait' wird Sie für die Änderung in allen Verzeichnissen wissen lassen. Wenn Sie mit diesen Verzeichnissen anders umgehen müssen, können Sie dies tun, nachdem Sie eine Benachrichtigung erhalten haben, indem Sie eine 'if-then-else' in bash verwenden. Alternativ könnten Sie mehrere verschiedene Beobachter in mehreren Prozessen starten. – redneb