파일 또는 디렉토리가 변경 될 때 쉘 스크립트를 실행하는 방법은 무엇입니까?
특정 파일이나 디렉토리가 변경 될 때 쉘 스크립트를 실행하고 싶습니다.
어떻게 쉽게 할 수 있습니까?
inotify-tools를 사용하십시오 .
이 스크립트를 사용하여 디렉토리 트리의 변경 사항에 대해 빌드 스크립트를 실행합니다.
#!/bin/bash -eu
DIRECTORY_TO_OBSERVE="js" # might want to change this
function block_for_change {
inotifywait --recursive \
--event modify,move,create,delete \
$DIRECTORY_TO_OBSERVE
}
BUILD_SCRIPT=build.sh # might want to change this too
function build {
bash $BUILD_SCRIPT
}
build
while block_for_change; do
build
done
용도 inotify-tools
. 빌드를 트리거하는 항목을 사용자 정의하는 방법은 inotifywait
매뉴얼 페이지 를 확인하십시오 .
당신은 시도 할 수 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
커널 파일 시스템 모니터 데몬 확인
http://freshmeat.net/projects/kfsmd/
방법은 다음과 같습니다.
http://www.linux.com/archive/feature/124903
이 스크립트는 어떻습니까? '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를 획득 할 수 있습니다 .
다른 옵션이 있습니다 : http://fileschanged.sourceforge.net/
특히 "디렉토리를 모니터링하고 새 파일이나 변경된 파일을 보관"하는 "예제 4"를 참조하십시오.
디버깅 목적으로 쉘 스크립트를 작성하고 저장시 실행되도록하려면 다음을 사용합니다.
#!/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 }')"
~ / .bashrc에 다음을 추가하십시오.
function react() {
if [ -z "$1" -o -z "$2" ]; then
echo "Usage: react <[./]file-to-watch> <[./]action> <to> <take>"
elif ! [ -r "$1" ]; then
echo "Can't react to $1, permission denied"
else
TARGET="$1"; shift
ACTION="$@"
while sleep 1; do
ATIME=$(stat -c %Z "$TARGET")
if [[ "$ATIME" != "${LTIME:-}" ]]; then
LTIME=$ATIME
$ACTION
fi
done
fi
}
inotifywait
당신을 만족시킬 수 있습니다.
다음은 이에 대한 일반적인 샘플입니다.
inotifywait -m /path -e create -e moved_to -e close_write | # -m is --monitor, -e is --event
while read path action file; do
if [[ "$file" =~ .*rst$ ]]; then # if suffix is '.rst'
echo ${path}${file} ': '${action} # execute your command
echo 'make html'
make html
fi
done
Example of using inotifywait
:
Suppose I want to run rails test
every time I modify a relevant file.
1. Make a list of the relevant files you want to watch:
You could do it manually, but I find ack
very helpful to make that list.
ack --type-add=rails:ext:rb,erb --rails -f > Inotifyfile
2. Ask inotifywait
to do the job
while inotifywait --fromfile Inotifyfile; do rails test; done
That's it!
NOTE: In case you use Vagrant to run the code on a VM, you might find useful the mhallin/vagrant-notify-forwarder extension.
UPDATE: Even better, make an alias
and get rid of the file:
alias rtest="while inotifywait $(ack --type-add=rails:ext:rb,erb --rails -f | tr \\n \ ); do rails test; done"
'Programing' 카테고리의 다른 글
MVC-RedirectToAction ()으로 데이터 전달 (0) | 2020.12.09 |
---|---|
char의 길이는 정확히 8 비트입니까? (0) | 2020.12.09 |
필요한 HTTP 응답 헤더 (0) | 2020.12.09 |
#if에서 사용되는 정의되지 않은 상수의 값은 무엇입니까? (0) | 2020.12.09 |
웹 인터페이스를 통해 TeamCity 서버 다시 시작 (0) | 2020.12.09 |