web-dev-qa-db-ja.com

ファイルがディレクトリにコピーされたときにコマンドを自動的に実行する

同じコンピューターの異なるパスにあるAとBという2つのフォルダーがあります。新しいファイルをフォルダーAに追加したら、それをフォルダーBに自動的にコピーしたい。

私のフォルダ:

/auto/std1/nat1/A
/auto/std2/nat2/B

ファイルをコピーするために私が現在行っていること:

cp -r A B

ただし、AからBへのすべての新しいファイルとフォルダーについて、このプロセスをバックグラウンドで自動的に実行する必要があります。

追加された質問/問題

ファイルをコピーしているときに、特定のファイルタイプに対して特定のアクションを実行する必要があります。例:フォルダーZipAファイルがある場合、unzipしたい自動的にフォルダB内のファイル。

これはCentOS 7`システム上にあります。

3
user88036

おまけの質問ごとに、以下で提供したシェルスクリプトのrsyncコマンドの下に次の行を追加します。私はコメントでこれを書きましたが、私はここに私の答えに公式に追加します:

    find /auto/std2/nat2/B -name '*.Zip' -exec sh -c 'unzip -d `dirname {}` {}' ';'

これは、rsyncを介してフォルダー/auto/std2/nat2/Aから/auto/std2/nat2/BにコピーされたすべてのZipファイルの解凍を処理します。



rsyncがインストールされている場合は、cronでrsyncにファイルのミラーリングを管理させるのはなぜですか?

スクリプトを作成myrsyncscript.sh

実行可能にすることを忘れないでください:chmod 700 myrsyncscript.sh

#!/bin/sh

LOCKFILE=/tmp/.hiddenrsync.lock

if [ -e $LOCKFILE ]
        then
        echo "Lockfile exists, process currently running."
        echo "If no processes exist, remove $LOCKFILE to clear."
        echo "Exiting..."
#        mailx -s "Rsync Lock - Lock File found" [email protected] <<+
#Lockfile exists, process currently running.
#If no processes exist, remove $LOCKFILE to clear.
#+
        exit
fi

touch $LOCKFILE
timestamp=`date +%Y-%m-%d::%H:%M:%s`
echo "Process started at: $timestamp" >> $LOCKFILE

## Run Rsync if no Lockfile
rsync -a --no-compress /auto/std1/nat1/A /auto/std2/nat2/B


echo "Task Finished, removing lock file now at `date +%Y-%m-%d::%H:%M:%s`"
rm $LOCKFILE

オプションの内訳:

-a is for archive, which preserves ownership, permissions etc.
--no-compress as there's no lack of bandwidth between local devices

検討する可能性のある追加オプション man rsync

-既存の無視

受信機に存在するファイルの更新をスキップする

- 更新

これにより、rsyncは宛先に存在し、ソースファイルよりも新しい変更時刻を持つファイルをスキップします。 (既存の宛先ファイルの変更時間がソースファイルと同じである場合、サイズが異なる場合は更新されます。)これは、シンボリックリンクやその他の特殊ファイルのコピーには影響しません。また、送信者と受信者のファイル形式の違いは、オブジェクトの日付に関係なく、常に更新にとって十分に重要であると見なされます。つまり、転送元に転送先のファイルがあるディレクトリがある場合、タイムスタンプに関係なく転送が行われます。

このオプションは除外ではなく転送ルールであるため、ファイルリストに含まれるデータには影響せず、削除には影響しません。受信者が転送を要求するファイルを制限するだけです。

このようにcronに追加し、頻度を最も快適なものに設定します。

crontab -eでcronを開き、以下を追加します。

### Every 5 minutes
*/5 * * * * /path/to/my/script/myrsyncscript.sh > /path/to/my/logfile 2>&1 

# * * * * *  command to execute
 # │ │ │ │ │
 # │ │ │ │ │
 # │ │ │ │ └───── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
 # │ │ │ └────────── month (1 - 12)
 # │ │ └─────────────── day of month (1 - 31)
 # │ └──────────────────── hour (0 - 23)
 # └───────────────────────── min (0 - 59)
3
devnull

初期変更に迅速に応答しながら、rsyncを最大5分ごとに1に抑えるために、ペースのあるイベント応答でinotifywaitを使用して@Izkataの提案を実装します。

#!/bin/sh
# usage: whateveryouwanttotcallthis "$directorytowatch" rsync args here

cd "$1" || { echo "${0##*/}: can't cd to $1"; exit 1; }
shift
rsync -nq "$@" || { echo "rsync doesn't like your $# arguments $@"; exit 1; }

notbefore=0
watchlock=.lock.inotifywait
rsynclock=.lock.rsync-pending

mkdir $watchlock ||
       { echo "${0##*/}: already running, rmdir '$PWD/$watchlock' if kill -9 took it out"
         exit 1;
       }
trap "rmdir '$watchlock'" 0 1 2 3 15

inotifywait -m -e close-write . |    # maybe also add move
        while read; do
                mkdir $rsynclock 2>&- || continue
                schedule=$(( notbefore <= (now=`date +%s`+2) ? (now+2)
                                                           : (notbefore) ))
                notbefore=$((schedule+300))
                ( ( trap "rmdir '$rsynclock'" 0 1 2 3 15
                    sleep $(( schedule-now ))
                  )
                  # substitute your payload here
                  rsync --exclude='.lock.*' "$@" \
                          || echo ssia | mail -s "${0##*/} '$PWD' rsync failed" opswatch
                ) &
        done

2秒の遅延は両方とも、小さなバーストの一括処理に役立ち、書き込みが完了したときに名前変更の一部の処理に時間をかけることができます。たぶん15秒が良いでしょう。

テストできません、Windows ATMでは、少なくともかなり近いと思います。

3
jthill

DevNullが提案したrsyncを定期的に使用することができます。個人的には inotify を使用します。それはあなたが見るフォルダーを与えることができる気の利いたツールです。監視を設定し、ファイルシステムの変更が発生するたびに通知します。次に、inotifyからのトリガーに基づいてrsyncをトリガーできます。

最後に説明する特定のケースでは、inotifyのトリガーを使用して、どのような変更が行われたかを確認し、単純なbashスクリプトを記述して、フォルダーAに追加されたZipファイルかどうかを確認できます。次に、Zipをコピーするだけでなく、フォルダB(またはその他の必要なもの)に解凍するだけです。

2
hRob