ディレクトリとコマンドの2つのパラメーターを取るbashスクリプトを作成しようとしています。このディレクトリの変更を監視する必要があり、何かが変更されたらコマンドを実行する必要があります。私はbashスクリプトを書くのは初めてで、何をしているのかよくわかりません。また、LinuxではなくMacを使用しています。任意のポインター、または外部リソースが大いに役立ちます。多くの人がインターネットでこれを試しており、誰もそれを正しくできないように見えることを知っています。私は本当にSASSの時計機能を真似しようとしています。
#!/bin/bash
#./watch.sh $PATH $COMMAND
DIR=$1
ls -l $DIR > $DIR/.begin
#this does not work
DIFFERENCE=$(diff .begin .end)
if [ $DIFFERENCE = '\n']; then
#files are same
else
$2
fi
ls -l $DIR > $DIR/.end
フォルダーの変更を監視し、更新時にlessコンパイラーを実行する例を次に示します。前提条件として、 npm
およびこれらのモジュール onchange が必要です。ノードコミュニティには、さまざまな監視コマンド(onchangeなど)が大量にあります。コンパイル済みの自己完結型のバイナリは知りません。
npm install less onchange -g
次に、次のようなものを使用できます。
onchange "./stylesheets/*.less" -- lessc main.less > main.css
Grunt answer よりもBASHコマンドを好む。
フォルダー(md5)を継続的に再帰的に監視し、変更時にコマンドを実行するには:
daemon() {
chsum1=""
while [[ true ]]
do
chsum2=`find src/ -type f -exec md5 {} \;`
if [[ $chsum1 != $chsum2 ]] ; then
compile
chsum1=$chsum2
fi
sleep 2
done
}
digest
がないため、OS Xで動作します。
Linuxでは、md5sum
コマンドの代わりにmd5
を使用できます。
メソッド1:
_#!/bin/sh
check() {
dir="$1"
chsum1=`digest -a md5 $dir | awk '{print $1}'`
chsum2=$chsum1
while [ $chsum1 -eq $chsum2 ]
do
sleep 10
chsum2=`digest -a md5 $dir | awk '{print $1}'`
done
eval $2
}
check $*
_
このスクリプトは、2つのパラメーター[ディレクトリ、コマンド]を取ります。 10秒ごとにスクリプトはcheck()
を実行して、フォルダーが変更されたことを確認します。そうでない場合はスリープし、サイクルが繰り返されます。
フォルダーが変更された場合は、eval
sコマンドになります。
メソッド2:
cronを使用してフォルダーを監視します。
Incronをインストールする必要があります。
_ Sudo apt-get install incron
_
そして、スクリプトは次のようになります。
_#!/bin/bash
eval $1
_
(指定されたディレクトリを監視するのはcronの仕事になるため、フォルダを指定する必要はありません)
完全で実用的な例はここにあります:
まだ誰も投稿していないとは信じられません。
最初に確認してくださいinotify-tools
がインストールされます。
次に、これらを次のように使用します。
logOfChanges="/tmp/changes.log.csv" # Set your file name here.
# Lock and load
inotifywait -mrcq $DIR > "$logOfChanges" &
IN_PID=$$
# Do your stuff here
...
# Kill and analyze
kill $IN_PID
cat "$logOfChanges" | while read entry; do
# Split your CSV, but beware that file names may contain spaces too.
# Just look up how to parse CSV with bash. :)
path=...
event=...
... # Other stuff like time stamps?
# Depending on the event…
case "$event" in
SOME_EVENT) myHandlingCode path ;;
...
*) myDefaultHandlingCode path ;;
done
または、--format
の代わりに -c
on inotifywait
はアイデアです。
ただman inotifywait
およびman inotifywatch
詳細については。
おそらくそれを行う最速の方法..(1G gitリポジトリでは、1秒未満で戻ります。)
#!/bin/bash
watch() {
echo watching folder $1/ every $2 secs.
while [[ true ]]
do
files=`find $1 -type f -mtime -$2s`
if [[ $files == "" ]] ; then
echo "nothing changed"
else
echo changed, $files
fi
sleep $2
done
}
watch folder 3
Mac OS Xでは、フォルダーをControlキーを押しながらクリックし、[フォルダーアクションのセットアップ]をクリックするだけです。これにより、アクションをフォルダーに添付できるようになります。つまり、実行するスクリプトです。
OS Xには多数のスクリプトがあらかじめ組み込まれていますが、独自のスクリプトを作成することもできます。
ほぼ3年後、このうなり声ベースのソリューションをお勧めします。
ここで実際の例を作成しました https://github.com/reggi/watch-execute 。
これがGruntfile.js
:
module.exports = function (grunt) {
grunt.initConfig({
Shell: {
run_file:{
command: 'sh ./bash.sh',
options: {
stdout: true
}
}
},
watch: {
run_file: {
files: ["./watchme/*"],
tasks: ["Shell:run_file"]
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-Shell');
};
watchfile
と呼ばれるこれらの種類の操作を簡素化する一般的なユーティリティを作成しました。
inotifywatch
よりも強力ではありませんが、よりシンプルで冗長なユーティリティを好みます。
目的のタスクについて、現在のディレクトリ内のファイルが変更されたかどうかを監視します。現在のディレクトリ内のすべてのファイルを再帰的にリストするには:
find . -type f
これらの各ファイルのタイムスタンプ情報を出力するには:
find . -type f -print0 | xargs -0 stat
これで、watchfile
ユーティリティを使用してこの出力を監視し、この情報が変更されたときにコマンドCMD
を実行できます。
watchfile -s "find . -type f -print0 | xargs -0 stat" -e CMD
#!/bin/bash
# Author: Devonte
# NGINX WATCH DAEMON
# Place file in root of nginx folder /etc/nginx
# This will test your nginx config on any change and
# if there are no problems it will reload your configuration
# USAGE: sh nginx-watch.sh
dir=`dirname $0`
checksum_initial=`tar -cf - $dir | md5sum | awk '{print $1}'`
checksum_now=$checksum_initial
# Start nginx
nginx
while true
do
sleep 3
checksum_now=`tar -cf - $dir | md5sum | awk '{print $1}'`
if [ $checksum_initial != $checksum_now ]; then
echo "[ NGINX ] A configuration file changed. Reloading..."
nginx -t && nginx -s reload;
fi
checksum_initial=$checksum_now
done
AppleScriptを使用しない理由
http://www.tuaw.com/2009/03/26/applescript-exploring-the-power-of-folder-actions-part-iii/
on adding folder items to this_folder after receiving added_items
tell application "Finder"
...
使用するテンプレートは次のとおりです。渡されたディレクトリの変更を120秒ごとにチェックし、ディレクトリ、ファイル、または名前パイプの作成時に通知します。何かが削除されたときにコマンドも実行したい場合は、追加のループの例について stackoverflow の他の答えを確認してください。
#!/usr/bin/env bash
Var_dir="${1:-/tmp}"
Var_diff_sleep="${2:-120}"
Var_diff_opts="--suppress-common-lines"
Func_parse_diff(){
_added="$(grep -E '>' <<<"${@}")"
if [ "${#_added}" != "0" ]; then
mapfile -t _added_list <<<"${_added//> /}"
_let _index=0
until [ "${#_added_list[@]}" = "${_index}" ]; do
_path_to_check="${Var_dir}/${_added_list[${_index}]}"
if [ -f "${_path_to_check}" ]; then
echo "# File: ${_path_to_check}"
Elif [ -d "${_path_to_check}" ]; then
echo "# Directory: ${_path_to_check}"
if [ -p "${_path_to_check}" ]; then
echo "# Pipe: ${_path_to_check}"
fi
let _index++
done
unset _index
fi
}
Func_watch_bulk_dir(){
_current_listing=""
while [ -d "${Var_dir}" ]; do
_new_listing="$(ls "${Var_dir}")"
_diff_listing="$(diff ${Var_dec_diff_opts} <(${Var_echo} "${_current_listing}") <(${Var_echo} "${_new_listing}"))"
if [ "${_diff_listing}" != "0" ]; then
Func_parse_diff "${_diff_listing}"
fi
_current_listing="${_new_listing}"
sleep ${Var_diff_sleep}
done
}
監視対象の各タイプのアクションについて、上記のecho
行をeval <some command>
に置き換える場合は、アクションの自動化により近くなります。また、スクリプト内で使用した場合に上記のように見えることを確認したい場合は、gpgおよびtarによる暗号化と復号化の自動化に取り組んでいるプロジェクトの最新の script version を確認してください。
最上位で作成/削除されているファイルのみをチェックする必要がある場合(サブフォルダーはチェックしない)、次を使用できます。
少ないリソースを使用するため、迅速に対応できます。変更されたファイルを確認するために使用します。
#!/bin/bash
file="$1"
shift
tmp=$(mktemp)
trap 'rm "$tmp"' EXIT
while true; do
while [ ! "$tmp" -ot "$file" ]; do
sleep 0.5
done
eval "$@ &"
echo $! > "$tmp"
wait
done