特定のファイルまたはディレクトリが変更されたときにシェル スクリプトを実行したいと考えています。
どうすれば簡単にできますか?
entr
ファイルが変更されたときに任意のコマンドを実行するツールを試すことができます。ファイルの例:
$ ls -d * | entr sh -c 'make && make test'
また:
$ ls *.css *.html | entr reload-browser Firefox
Changed!
またはファイルfile.txt
の保存時に印刷します。
$ echo file.txt | entr echo Changed!
ディレクトリ-d
には を使用しますが、ループ内で使用する必要があります。例:
while true; do find path/ | entr -d echo Changed; done
また:
while true; do ls path/* | entr -pd echo Changed; done
inotify-toolsを使用します。
リンクされたGithubページにはいくつかの例があります。これがその1つです。
#!/bin/sh
cwd=$(pwd)
inotifywait -mr \
--timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \
-e close_write /tmp/test |
while read -r date time dir file; do
changed_abs=${dir}${file}
changed_rel=${changed_abs#"$cwd"/}
rsync --progress --relative -vrae 'ssh -p 22' "$changed_rel" \
usernam@example.com:/backup/root/dir && \
echo "At ${time} on ${date}, file $changed_abs was backed up via rsync" >&2
done
このスクリプトはどうですか?「stat」コマンドを使用してファイルのアクセス時間を取得し、アクセス時間に変更があるたびに (ファイルがアクセスされるたびに) コマンドを実行します。
#!/bin/bash
while true
do
ATIME=`stat -c %Z /path/to/the/file.txt`
if [[ "$ATIME" != "$LTIME" ]]
then
echo "RUN COMMNAD"
LTIME=$ATIME
fi
sleep 5
done
前述のように、inotify-toolsはおそらく最良のアイデアです。ただし、楽しみのためにプログラミングしている場合は、 tail -fを適切に適用することで、ハッカーXPを獲得することができます。
デバッグ目的で、シェル スクリプトを作成して保存時に実行する場合は、次のようにします。
#!/bin/bash
file="$1" # Name of file
command="${*:2}" # Command to run on change (takes rest of line)
t1="$(ls --full-time $file | awk '{ print $7 }')" # Get latest save time
while true
do
t2="$(ls --full-time $file | awk '{ print $7 }')" # Compare to new save time
if [ "$t1" != "$t2" ];then t1="$t2"; $command; fi # If different, run command
sleep 0.5
done
次のように実行します
run_on_save.sh myfile.sh ./myfile.sh arg1 arg2 arg3
編集: Ubuntu 12.04 で上記のテストを行いました。Mac OS の場合は、ls 行を次のように変更します。
"$(ls -lT $file | awk '{ print $8 }')"
別のオプションは次のとおりです:http://fileschanged.sourceforge.net/
特に「ディレクトリを監視し、新しいファイルまたは変更されたファイルをアーカイブする」「例4」を参照してください。