2016-09-12 17 views
0

私は次のスクリプト(OEL5.6で実行中のシェルスクリプト)を持っています。このスクリプトは現在、指定されたディレクトリ(データベーステーブルで指定されたもの)からファイルを選択し、ディレクトリ&のファイルマスクベース。スクリプトは現時点ではうまく動作しますが、この実装では、他のすべてのフォルダがスクリプトを完了するまで、1つのフォルダが大量のファイルを処理しても、そのフォルダが終了するまでは終了しません。次の走りまで拾わなければならない。私はこれに似たアプローチを使ってみたいと思いますが、すべてのフォルダを一度実行して終了するのではなく、新しいファイルのフォルダを常時チェックしてから、バックグラウンドでデーモンの多くを実行するようにします。これをラップするよりもむしろアイデアをループするwhile true?私はこの例のコードを少し省略して、これを除外しました。シェルスクリプトファイルウォッチャーの並行性

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

どのようなOSですか? – redneb

+0

OSはOELです。5.6 –

答えて

2

ひとつのアイデアは、変更のためのディレクトリを監視するためにinotify-toolsからinotifywaitを使用することです。これは、ディレクトリの変更を常にスキャンするより効率的です。そのようなもの

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

現在のプロセスは、feed_name、directory、filemask、...のような設定テーブルによって実行されます。 inotifywaitを使用してもこの方法を使用できますか?各ディレクトリとファイルマスクコンボには、データベーステーブルから取得した私の例では "another_script.sh"に渡される異なるパラメータが適用されています。 –

+0

'inotifywait'はすべてのディレクトリの変更を知らせます。これらのディレクトリを別々に扱う必要がある場合は、通知を受け取った後、bashで 'if-then-else'を使って行うことができます。また、複数のプロセスで複数のウォッチャーを起動することもできます。 – redneb