파일이 바뀔 때마다 명령을 실행하는 방법?


388

나는 파일이 바뀔 때마다 명령을 실행하는 빠르고 간단한 방법을 원한다. 나는 아주 간단하고, 터미널에서 돌아가고 나가 그 파일에 대한 작업을 마칠 때마다 닫을 수있는 무언가를 원한다.

현재, 나는 이것을 사용하고있다 :

while read; do ./myfile.py ; done

그리고 그 터미널로 가서 들어가다 , 그 파일을 편집자에게 저장할 때마다. 내가 원하는 것은 다음과 같습니다.

while sleep_until_file_has_changed myfile.py ; do ./myfile.py ; done

아니면 다른 솔루션으로 쉽게.

BTW : 저는 Vim을 사용하고 있습니다. BufWrite에서 뭔가를 실행하기 위해 자동 명령을 추가 할 수 있다는 것을 알고 있습니다. 그러나 이것은 제가 지금 원하는 해결책이 아닙니다.

최신 정보: 나는 가능한 한 간단하고 버려 질 수있는 것을 원한다. 게다가, 프로그램 출력을보고 싶기 때문에 터미널에서 뭔가를 실행하고 싶습니다 (오류 메시지를보고 싶습니다).

답변 정보 : 모든 답변 주셔서 감사합니다! 그들 모두는 매우 좋으며, 각각은 다른 사람들과 매우 다른 접근 방식을 취합니다. 나는 단 하나만 받아 들일 필요가 있기 때문에, 내가 가장 우아하지 않다는 것을 알고 있긴하지만, 실제로 사용했던 것을 받아들입니다. (간단하고 신속하며 기억하기 쉽습니다.)


가능한 교차 사이트 복제본 : stackoverflow.com/questions/2972765/... (비록 여기에 주제 =))
Ciro Santilli 新疆改造中心 六四事件 法轮功

크로스 사이트가 중복되기 전에 참조했는데 거부되었습니다 : S;)
Francisco Tapia

4
조나단 하틀리 (Jonathan Hartley)의 솔루션은 여기에있는 다른 솔루션을 기반으로하며 가장 많이 투표 한 답변에있는 몇 가지 수정 사항을 놓치고 비효율적 인 큰 문제를 수정합니다. 수락 된 답변을 자신의 답변으로 변경하십시오. github.com/tartley/rerun2 (또는 그 결함이없는 다른 솔루션으로)
nealmcb

답변:


370

간단하고, 사용하기 inotifywait (배포판의 설치 inotify-tools 꾸러미):

while inotifywait -e close_write myfile.py; do ./myfile.py; done

또는

inotifywait -q -m -e close_write myfile.py |
while read -r filename event; do
  ./myfile.py         # or "./$filename"
done

첫 번째 스 니펫은 더 간단하지만 중요한 단점이 있습니다. inotifywait 실행되지 않습니다 (특히 myfile 실행 중). 두 번째 스 니펫에는이 결함이 없습니다. 그러나 파일 이름에는 공백이 들어 있지 않다고 가정합니다. 그게 문제라면, --format 옵션을 사용하여 파일 이름을 포함하지 않도록 출력을 변경하십시오.

inotifywait -q -m -e close_write --format %e myfile.py |
while read events; do
  ./myfile.py
done

어느 쪽이든 제한이 있습니다 : 일부 프로그램이 myfile.py 기존 파일에 쓰기보다는 다른 파일로 myfile, inotifywait 죽을 것이다. 많은 편집자들이 그런 식으로 일합니다.

이 제한을 극복하려면 inotifywait 디렉토리에 :

inotifywait -e close_write,moved_to,create -m . |
while read -r directory events filename; do
  if [ "$filename" = "myfile.py" ]; then
    ./myfile.py
  fi
done

또는 다음과 같은 기본 기능을 사용하는 다른 도구를 사용하십시오. Incron (파일 수정시 이벤트 등록 가능) 또는 fswatch (다른 여러 Unix 변종에서도 작동하는 툴로 각 변종의 Linux inotify 아날로그 사용).


46
나는이 모든 것을 캡슐화하여 사용하기 쉬운 (간단히 말해서 배쉬 트릭으로) sleep_until_modified.sh 스크립트 : bitbucket.org/denilsonsa/small_scripts/src
Denilson Sá Maia

14
while sleep_until_modified.sh derivation.tex ; do latexmk -pdf derivation.tex ; done 환상적이다. 고맙습니다.
Rhys Ulerich

5
inotifywait -e delete_self 나를 위해 잘 작동하는 것 같습니다.
Kos

3
간단하지만 두 가지 중요한 문제가 있습니다. 이벤트가 누락 될 수 있습니다 (루프의 모든 이벤트). 반복적 인 대규모 폴더의 경우이 솔루션을 느리게 만들 때마다 inotifywait 초기화가 수행됩니다.
Wernight

5
몇 가지 이유 while inotifywait -e close_write myfile.py; do ./myfile.py; done 명령 (bash 및 zsh)을 실행하지 않고 항상 종료됩니다. 이 작업을하려면 추가해야했습니다. || true, 예 : while inotifywait -e close_write myfile.py || true; do ./myfile.py; done
ideasman42

132

엔트리 ( http://entrproject.org/ )는 inotify에 더 친숙한 인터페이스를 제공합니다 (또한 * BSD 및 Mac OS X도 지원합니다).

여러 파일을 지정하는 것을 매우 쉽게 만듭니다 ( ulimit -n ), 교체되는 파일을 처리하는 번거 로움을 덜어 주며 더 적은 bash 구문을 필요로합니다.

$ find . -name '*.py' | entr ./myfile.py

나는 현재 수정중인 코드에 대한 단위 테스트를 실행하기 위해 전체 프로젝트 소스 트리에서이 코드를 사용하고 있으며 이미 워크 플로를 크게 향상시켜 왔습니다.

좋아하는 플래그 -c (실행 사이의 화면을 지우십시오) -d (모니터링 된 디렉토리에 새 파일이 추가되면 종료) 유연성을 추가하십시오. 예를 들면 다음과 같습니다.

$ while sleep 1 ; do find . -name '*.py' | entr -d ./myfile.py ; done

현재 2018 년 초부터 아직 개발 중이며 데비안 & amp; 우분투 ( apt install entr ); 어떤 경우에도 작성자의 레포에서 건물은 통증이 없었습니다.


1
새 파일 및 수정 사항을 처리하지 않습니다.
Wernight

2
@Wernight - 2014 년 5 월 7 일부터 entr에 새로운 -d 깃발; 조금 길어졌지만 할 수 있어요. while sleep 1 ; do find . -name '*.py' | entr -d ./myfile.py ; done 새로운 파일을 다루는 것.
Paul Fenney

1
또한 debian jessie / 8.2에서 적어도 debian repos에서 사용할 수 있습니다.
Peter V. Mørch

5
최고의 하나는 내가 OS X에서 발견. fswatch는 너무 많은 펑키 이벤트를 잡아 내고 그 이유를 알기 위해 시간을 보내고 싶지 않습니다.
dtc

3
그것은 주목할 가치가있다. 엔트리 홈 브루에서 사용할 수 있습니다. brew install entr 예상대로 작동 할 것입니다.
jmarceli

102

필자는 Python 프로그램을 작성하여이를 정확히 수행했습니다. 언제 바뀌 었는가? .

사용법은 간단합니다.

when-changed FILE COMMAND...

또는 여러 파일보기 :

when-changed FILE [FILE ...] -c COMMAND

FILE 디렉토리 일 수 있습니다. 재귀 적으로보기 -r. 용도 %f 명령에 파일 이름을 전달하십시오.


1
@ysangkok 예 코드의 최신 버전에서 않습니다 :)
joh

4
이제 "pip install when changed"에서 사용 가능합니다. 아직도 잘 작동합니다. 감사.
A. L. Flanagan

2
먼저 화면을 지우려면 다음을 사용할 수 있습니다. when-changed FILE 'clear; COMMAND'.
Dave James Miller

1
이 대답은 Windows에서도 가능하기 때문에 훨씬 낫습니다. 그리고이 사람은 실제로 답을 얻기 위해 프로그램을 작성했습니다.
Wolfpack'08

4
모두들 반가워요! when-changed 이제는 교차 플랫폼입니다! 최신 체크 아웃 0.3.0 릴리스 :)
joh

47

이 스크립트는 어때? 그것은 stat 명령을 사용하여 파일의 액세스 시간을 가져오고 액세스 시간이 변경 될 때마다 (파일에 액세스 할 때마다) 명령을 실행합니다.

#!/bin/bash

### Set initial time of file
LTIME=`stat -c %Z /path/to/the/file.txt`

while true    
do
   ATIME=`stat -c %Z /path/to/the/file.txt`

   if [[ "$ATIME" != "$LTIME" ]]
   then    
       echo "RUN COMMAND"
       LTIME=$ATIME
   fi
   sleep 5
done

1
하지 않을 것이다. stat 수정 된 시간은 "파일이 변경 될 때마다"더 나은 대답일까요?
Xen2050

1
초당 여러 번 실행하면 디스크에 많은 읽기가 발생합니까? 또는 fstat 시스템 호출이 자동으로 이러한 응답을 어떻게 든 캐시합니까? 변경을 할 때마다 내 c 코드를 컴파일하는 일종의 '쓸데없는 시계'를 작성하려고합니다.
Oskenso Kashi

사전에 파일 이름을 알고 있다면이 기능이 유용합니다. 파일 이름을 스크립트에 전달하는 것이 더 좋습니다. 많은 파일 이름 (예 : "mywatch * .py")을 전달할 수 있다면 더 좋을 것입니다. 서브 디렉토리의 파일에서도 재귀 적으로 작동 할 수 있다면 더 좋을 것입니다. 다른 솔루션의 일부는 그렇게합니다.
Jonathan Hartley

2
누군가가 무거운 읽기에 대해 궁금해하는 경우를 대비해서, 우분투 17.04에서이 스크립트를 0.05 초의 수면 상태로 테스트했습니다. vmstat -d 디스크 액세스를 감시합니다. 리눅스는 이런 종류의 캐싱에 환상적인 일을하고있는 것 같습니다 : D
Oskenso Kashi

"COMMAND"에 오타가 있는데, 나는 고치려고했지만 S.O. "편집이 6 자 미만이어야합니다"
user337085

29

Vim을 사용하는 솔루션 :

:au BufWritePost myfile.py :silent !./myfile.py

하지만이 솔루션을 원하지 않습니다. 입력하기가 짜증나기 때문에 입력 할 내용을 정확히 기억하기가 어려우며 효과를 실행 취소하기가 약간 어렵습니다 (실행할 필요가 있음). :au! BufWritePost myfile.py ). 또한이 솔루션은 명령 실행이 완료 될 때까지 Vim을 차단합니다.

이 솔루션을 다른 사람들에게 도움이 될 수 있도록 여기에 추가했습니다.

프로그램 출력을 표시하려면 (그리고 편집 흐름을 완전히 중단 시키려면 Enter 키를 누를 때까지 출력이 편집기를 몇 초 동안 씁니다.) :silent 명령.


이것과 결합 할 때 이것은 아주 좋을 수 있습니다. entr (아래 참조) - 단지 vim이 entr이보고있는 더미 파일을 만지고, 나머지는 백그라운드에서 수행하도록하십시오. tmux send-keys 당신이 그런 환경에있게되면 :)
Paul Fenney

좋은! 당신은 당신의 매크로를 만들 수 있습니다. .vimrc 파일
ErichBSchulz

24

일이 생기면 npm 설치, nodemon 아마도 OS X에서 특히 inotify 도구가없는 가장 쉬운 방법 일 것입니다. 폴더가 변경 될 때 명령 실행을 지원합니다.


3
그러나 .js 및 .coffee 파일 만 감시합니다.
zelk

5
현재 버전은 다음과 같은 명령을 지원하는 것으로 보입니다. nodemon -x "bundle exec rspec" spec/models/model_spec.rb -w app/models -w spec/models
kek

1
나는 더 많은 정보를 갖고 싶지만, osx는 fsevents를 추적하는 방법을 가지고있다.
ConstantineK

1
OS X에서도 다음을 사용할 수 있습니다. 데몬 시작 ~와 WatchPaths 내 링크에 표시된 키.
Adam Johns

14

rerun2 ( github에 )는 다음과 같은 형태의 10 줄짜리 Bash 스크립트입니다 :

#!/usr/bin/env bash

function execute() {
    clear
    echo "$@"
    eval "$@"
}

execute "$@"

inotifywait --quiet --recursive --monitor --event modify --format "%w%f" . \
| while read change; do
    execute "$@"
done

github 버전을 PATH에 'rerun'으로 저장하고 다음을 사용하여 호출하십시오.

rerun COMMAND

현재 디렉토리 내에서 파일 시스템 수정 이벤트가 발생할 때마다 COMMAND를 실행합니다 (재귀 적입니다.).

그것에 대해 좋아할만한 것들 :

  • inotify를 사용하므로 폴링보다 응답 속도가 빠릅니다. '저장'을 누를 때마다 서브 밀리 초 단위 테스트를 실행하거나 graphviz 도트 파일을 렌더링하는 데 이상적입니다.
  • 너무 빠르기 때문에 성능상의 이유 때문에 node_modules와 같은 큰 subdir을 무시하도록하지 않아도됩니다.
  • 초보자에게는 반응이 빨라요. 시작과 실행 중 한 번만 inotifywait를 호출하고 반복 할 때마다 시계를 설치하는 데 드는 비용이 많이 들기 때문입니다.
  • 배쉬의 12 줄 밖에 안돼.
  • Bash이기 때문에 Bash 프롬프트에서 입력 한 것과 똑같은 명령을 해석합니다. (아마도 다른 쉘을 사용하면 덜 멋지기도합니다.)
  • 이 페이지의 다른 inotify 솔루션과 달리 COMMAND가 실행되는 동안 발생하는 이벤트는 손실되지 않습니다.
  • 첫 번째 이벤트에서는 COMMAND가 정확히 한 번 실행되기 전에 다른 이벤트가 무시되는 동안 'dead time'이 0.15 초 동안 입력됩니다. 이것은 버퍼를 저장할 때 Vi 나 Emacs가 수행하는 create-write-move 댄스로 인해 발생하는 이벤트의 혼란으로 인해 느리게 실행되는 테스트 스위트를 여러 번 실행하지 않아도되도록하기위한 것입니다. COMMAND가 실행 중일 때 발생하는 모든 이벤트는 무시되지 않고 두 번째 데드 타임과 후속 실행을 유발합니다.

사람이 그것에 대해 싫어하는 것 :

  • 그것은 inotify를 사용하므로 Linuxland 밖에서는 작동하지 않습니다.
  • 그것은 inotify를 사용하기 때문에, 사용자 inotify 시계의 최대 수보다 많은 파일을 포함하는 디렉토리를 보려고 할 때 barf를 사용합니다. 기본적으로 이것은 내가 사용하는 다른 컴퓨터에서 약 5,000에서 8,000으로 설정되어 있지만 증가하기 쉽습니다. 만나다 https://unix.stackexchange.com/questions/13751/kernel-inotify-watch-limit-reached
  • Bash 별명을 포함하는 명령을 실행하는 데 실패합니다. 나는 이것이 일하는 것을 맹세할 수 있었다. 원칙적으로 이것은 Bash이고, 서브 쉘에서 COMMAND를 실행하지 않기 때문에, 나는 이것이 작동 할 것으로 기대합니다. 나는 왜 사람들이 그것을 안다면, 듣고 싶다. 이 페이지의 다른 많은 솔루션은 이러한 명령을 실행할 수 없습니다.
  • 개인적으로 나는 수동으로 COMMAND를 추가로 실행하기 위해 실행중인 터미널의 키를 누를 수 있었으면 좋겠다. 어떻게 든 간단히 추가 할 수 있을까요? 동시에 실행되는 'read -n1'루프도 동시에 실행됩니까?
  • 지금은 터미널을 지우고 각 반복마다 COMMAND를 인쇄하도록 코드를 작성했습니다. 어떤 사람들은 명령 줄 플래그를 추가하여이 기능을 해제하는 등의 작업을 수행 할 수 있습니다. 그러나 이렇게하면 크기와 복잡성이 여러 배로 증가합니다.

이것은 @ cychoi의 anwer의 세련미입니다.


1
네가 사용해야한다고 생각해. "$@" 대신에 $@공백을 포함하는 인수로 올바르게 작업하기 위해. 하지만 동시에 eval이는 재실행 사용자에게 인용시에 특히주의해야합니다.
Denilson Sá Maia

Denilson에게 감사드립니다. 따옴표를주의 깊게 작성해야하는 경우를 보여 주실 수 있습니까? 나는 그것을 지난 24 시간 동안 사용 해왔고 지금까지는 공백과 관련하여 어떤 문제도 보지 못했으며, 면밀히 아무것도 인용 한 - 방금 호출 된 rerun 'command'. "$ @"를 사용하면 사용자가 다음과 같이 호출 할 수 있다고 말하는 것입니까? rerun command (따옴표없이)? 그것은 나를 위해 유용하게 보이지 않는다 : 나는 일반적으로 Bash가하기를 원하지 않는다. 어떤 다시 실행하기 위해 명령을 전달하기 전에 명령 처리. 예 : 명령에 "echo $ myvar"가 포함되어 있으면 각 반복에서 myvar의 새 값을보고 싶습니다.
Jonathan Hartley

좋아요. rerun foo "Some File" 파산할지 모른다. 하지만 당신이 사용하고 있기 때문에 eval, 다음과 같이 다시 쓸 수 있습니다. rerun 'foo "Some File". 때때로 경로 확장이 공백을 가져올 수 있습니다. rerun touch *.foo 가능성이 높아지고 rerun 'touch *.foo' 약간 다른 의미가 있습니다 (경로 확장은 한 번만 또는 여러 번 발생 함).
Denilson Sá Maia

도와 주셔서 감사합니다. 네: rerun ls "some file" 공백으로 인해 부서진다. rerun touch *.foo* 보통 잘 작동하지만 * .foo와 일치하는 파일 이름에 공백이 있으면 실패합니다. 어떻게 도와 주셔서 감사합니다. rerun 'touch *.foo' 다른 의미를 지니고 있지만, 작은 따옴표가있는 버전은 내가 원하는 의미라고 생각합니다. 다시 명령을 입력 한 것처럼 재실행의 반복을 원합니다. 따라서 필요 *.foo 각 반복마다 확장됩니다. 나는 당신의 제안을 시험해 그들의 효과를 시험해 볼 것이다 ...
Jonathan Hartley

이 홍보에 대한 더 많은 토론 ( github.com/tartley/rerun2/pull/1 ) 다른 사람.
Jonathan Hartley

12

다음은 간단한 쉘 Bourne 쉘 스크립트입니다.

  1. 모니터 할 파일과 명령 (필요한 경우 인수 사용)의 두 인수를 취합니다.
  2. 감시하고있는 파일을 / tmp 디렉토리에 복사합니다.
  3. 2 초마다 검사하여 감시중인 파일이 사본보다 새로운 지 확인합니다.
  4. 최신 버전 인 경우 사본을 최신 원본으로 덮어 쓰고 명령을 실행합니다
  5. Ctrl-C를 누를 때 자동으로 정리됩니다.

    #!/bin/sh  
    f=$1  
    shift  
    cmd=$*  
    tmpf="`mktemp /tmp/onchange.XXXXX`"  
    cp "$f" "$tmpf"  
    trap "rm $tmpf; exit 1" 2  
    while : ; do  
        if [ "$f" -nt "$tmpf" ]; then  
            cp "$f" "$tmpf"  
            $cmd  
        fi  
        sleep 2  
    done  
    

이것은 FreeBSD에서 작동합니다. 내가 생각할 수있는 유일한 이식성 문제는 다른 유닉스가 mktemp (1) 명령을 가지고 있지 않은 경우이지만,이 경우에는 임시 파일 이름을 하드 코딩 할 수 있습니다.


9
폴링 만이 이식 할 수있는 방법이지만, 대부분의 시스템에는 파일 변경 알림 메커니즘 (Linux에서는 inotify, FreeBSD에서는 kqueue)이 있습니다. 당신이 할 때 심각한 인용 문제가 있습니다. $cmd, 다행히도 쉽게 고칠 수 있습니다. cmd 변수와 실행 "$@". 스크립트가 큰 파일을 모니터링하는 데는 적합하지 않지만이를 대체하여 수정할 수 있습니다. cp 으로 touch -r (당신은 내용이 아닌 날짜 만 필요합니다). 휴대 성, -nt 테스트에는 bash, ksh 또는 zsh가 필요합니다.
Gilles

10

설치할 수없는 사람들을 위해 inotify-tools 나처럼, 이것은 유용 할 것이다.

watch -d -t -g ls -lR

출력이 변경되면이 명령이 종료되고, ls -lR 크기와 날짜가있는 모든 파일과 디렉토리를 나열하므로 파일이 변경되면 사람이 말한대로 명령을 종료해야합니다.

-g, --chgexit
          Exit when the output of command changes.

나는이 대답이 누군가에 의해 읽혀지지 않을지도 모른다는 것을 알고 있지만 누군가가 그것에 도달하기를 바랍니다.

명령 줄 예 :

~ $ cd /tmp
~ $ watch -d -t -g ls -lR && echo "1,2,3"

다른 터미널 열기 :

~ $ echo "testing" > /tmp/test

이제 첫 번째 터미널에서 출력됩니다. 1,2,3

간단한 스크립트 예제 :

#!/bin/bash
DIR_TO_WATCH=${1}
COMMAND=${2}

watch -d -t -g ls -lR ${DIR_TO_WATCH} && ${COMMAND}

4
좋은 해킹. 테스트를 거쳤으며 목록이 길고 변경된 파일이 화면 외부에있을 때 문제가있는 것으로 보입니다. 작은 수정은 다음과 같이 될 수 있습니다. watch -d -t -g "ls -lR tmp | sha1sum"
Atle

1
매초마다 솔루션을 시청하면 영원히 작동하고 일부 파일이 변경된 경우에만 MY_COMMAND를 실행합니다. watch -n1 "watch -d -t -g ls -lR & amp; & amp; MY_COMMAND"
mnesarco

내 버전의 시계 (Linux, watch from procps-ng 3.3.10 ) 그 간격 동안 float 초를 받아 들인다. watch -n0.2 ... 1 초마다 5 분마다 폴링합니다. 그 건강한 sub-millisecond 단위 테스트에 좋습니다.
Jonathan Hartley

8

좀 봐. Incron . cron과 유사하지만 시간 대신에 inotify 이벤트를 사용합니다.


이 작업을 수행 할 수 있지만이 페이지의 다른 솔루션과 비교하여 incron 항목을 작성하는 것은 상당한 노동 집약적 프로세스입니다.
Jonathan Hartley

7

노드 젝스 (NodeJs) fsmonitor :

  1. 설치

    sudo npm install -g fsmonitor
    
  2. 명령 줄에서 (예 : 로그를 모니터링하고 하나의 로그 파일이 변경되면 "소매점")

    fsmonitor -s -p '+*.log' sh -c "clear; tail -q *.log"
    

참고 사항 :이 예는 tail -F -q *.log, 나는 생각한다.
Volker Siegel

6

Linux에서 :

man watch

watch -n 2 your_command_to_run

2 초마다 명령을 실행합니다.

명령을 실행하는 데 2 ​​초 이상 걸리는 경우 시계가 완료 될 때까지 기다렸다가 다시 수행하십시오.


이는 다소 단순하지만 다소 낭비 일뿐 아니라 스타일을 실시간 변경하는 것과 같은 개발 작업에도 쉽습니다.
Xeoncross

2
명령을 실행하는 데 2 ​​초 이상이 걸리면 어떻게됩니까?
thirtythreeforty

@thirtythreeforty Ubuntu에 대한 간단한 실험은 명령이 실행되는 데 걸리는 시간과 상관없이 시계가 전체 2 초를 기다리는 것을 보여줍니다. FWIW에서는 수면 기간을 '-n'으로 지정할 수 있으며 최소 0.1 초가 소요됩니다.
Jonathan Hartley

5

특히이 플러그인으로 가드를 살펴보십시오.

https://github.com/hawx/guard-shell

프로젝트 디렉토리의 패턴을 원하는 수만큼 보도록 설정하고 변경이 발생하면 명령을 실행할 수 있습니다. 좋은 기회 일지라도, 우선 당신이하려는 일에 사용할 수있는 플러그인이 있습니다.


5

당신이 가지고 있다면 노르 드 몬 설치하면 다음 작업을 수행 할 수 있습니다.

nodemon -w <watch directory> -x "<shell command>" -e ".html"

제 경우에는 html을 로컬에서 편집하고 파일이 변경되면 원격 서버로 보내십시오.

nodemon -w <watch directory> -x "scp filename jaym@jay-remote.com:/var/www" -e ".html"

4

프로그램에서 일종의 로그 / 출력을 생성하는 경우 스크립트에 의존하는 로그 / 출력에 대한 규칙을 사용하여 Makefile을 만들 수 있습니다.

while true; do make -s my_target; sleep 1; done

또는 가짜 타겟을 생성하고 스크립트를 호출하여 가짜 타겟을 터치 할 수 있습니다 (스크립트에 따라 다름).


11
while sleep 1 ; do something ; done 약간 낫다. while true ; do something ; sleep 1 ; done. 적어도 Ctrl + C를 누르면 쉽게 멈 춥니 다.
Denilson Sá Maia

절전 모드를 제거하면 CPU가 과열되어 노트북에서 배터리 수명을 저하시키는 바쁜 루프가 발생합니까?
Steven Lu

2
@ StevenLu : 아니, 잠은 바쁜 대기가 아닙니다. 문제는 수면이 몸에 있으면 Control-C가 수면을 종료하고 루프가 다시 시작된다는 것입니다. 루프를 시작하는 전력 사용은 중요하지 않습니다. 터미널에서 직접 사용해보십시오. 몸에 잠을 자면 Control-C를 잡아서 작동시켜야합니다.
Janus Troelsen

권리. 나는 그것을 놓쳤다 고 생각하고 잠이 루프 상태로 여전히 존재하는 것을 보지 못했습니다. 그 작은 비틀기는 꽤 굉장합니다.
Steven Lu

4

2
이것은 투표 기능을 갖춘 200 행의 Bash 스크립트입니다. stat 주어진 파일 이름에서 실행 md5sum 이 값이 변경되면 주어진 명령을 다시 실행합니다. Bash이기 때문에 Bash 프롬프트에서 입력 한 것처럼 정확히 주어진 명령을 실행하는 것이 좋을 것 같습니다. 반대로 다른 언어로 작성된 대부분의 솔루션은 예를 들어 다음과 같은 셸 별칭을 포함하는 명령을 실행하지 못합니다. ll )
Jonathan Hartley

4

지키는 개 Python 프로젝트이며 찾고있는 것일 수 있습니다.

지원되는 플랫폼

  • 리눅스 2.6 (inotify)
  • Mac OS X (FSEvents, 큐)
  • FreeBSD / BSD (큐큐)
  • Windows (I / O 완료 포트가있는 ReadDirectoryChangesW, ReadDirectoryChangesW 작업자 스레드)
  • OS 독립적 (디렉토리 스냅 샷을 위해 디스크 폴링 및 주기적으로 비교, 느리고 권장되지 않음)

그냥 명령 줄 래퍼를 썼다. watchdog_exec:

예제 실행

현재 디렉토리의 파일 및 폴더와 관련된 fs 이벤트에서 다음을 실행하십시오. echo $src $dst fs 이벤트가 수정되지 않은 한 다음 명령을 실행하십시오. python $src 명령.

python -m watchdog_exec . --execute echo --modified python

짧은 인수 사용 및 이벤트가 포함될 때만 실행되도록 제한 " 본관 .py ":

python -m watchdog_exec . -e echo -a echo -s __main__.py

편집 : 그냥 Watchdog라는 공식적인 CLI가 발견 watchmedo, 그래서 그것도 확인하십시오.


4

개선 된 질의 대답 .

이 버전이 실행됩니다. inotifywait 한 번 이벤트를 모니터링합니다 (예 : modify ). 그런 inotifywait 하지 않는다 발생한 모든 이벤트마다 다시 실행해야합니다.

빠르고 쉽습니다! (큰 디렉토리를 재귀 적으로 모니터링하는 경우에도)

inotifywait --quiet --monitor --event modify FILE | while read; do
    # trim the trailing space from inotifywait output
    REPLY=${REPLY% }
    filename=${REPLY%% *}
    # do whatever you want with the $filename
done

이것은 Linux 전용 사용자를위한 페이지에서 가장 좋은 답변입니다. 루프 내부의 내용을 'execute $ @'로 바꾸면 사용자는이 스크립트를 자신의 명령에 전달하여 실행할 수 있습니다. ". scriptname COMMAND"와 같은 것을 사용하여 쉘 별명을 포함하는 명령과 함께 작동합니다. 이것은 여전히 ​​PATH에서 scriptname을 찾습니다.
Jonathan Hartley

나는 REPLY를 읽는 동안 '넣으려고한다고 생각하십니까?
Jonathan Hartley

1
나는이 수정 프로그램을 내 자신의 대답으로 굴렸다 :이 페이지에서 'rerun2'검색
Jonathan Hartley

1
Fu * king 매뉴얼을 읽음으로써 help read, If no NAMEs are supplied, the line read is stored in the REPLY variable..
cychoi

1
해명 해줘서 고마워. 그것의 단계적 실행을위한 고맙습니다! 나는 그 주석을 지웠을 것이지만 물론 지금은하지 않을 것이다.
Jonathan Hartley

3

프로그래밍 측면에 대해서는 조금 더 설명 하겠지만, 상속하다 . 여러 언어로 된 구현이 있습니다. 항의하다 피니 티피 화하다 .

이 라이브러리는 단일 파일 또는 전체 디렉토리를 모니터하고 조치가 _ 견될 때 이벤트를 리턴합니다. 반환 된 정보에는 파일 이름, 작업 (작성, 수정, 이름 바꾸기, 삭제) 및 기타 유용한 정보가 포함됩니다.


3

FreeBSD 솔루션을 찾고 계시다면 다음 포트를 사용하십시오.

/usr/ports/sysutils/wait_on

3

나는 단순함을 좋아한다. while inotifywait ...; do ...; done 그러나 두 가지 문제가 있습니다.

  • 파일 변경 중에 발생하는 do ...; 의지 놓친
  • 느린 재귀 모드에서 사용할 때

그래서 나는 헬퍼 스크립트를 만들어서 inotifywait 그 제한없이 : inotifyexec

이 스크립트를 경로에 삽입하는 것이 좋습니다. ~/bin/. 사용법은 명령을 실행하여 설명합니다.

예: inotifyexec "echo test" -r .


regex 패턴 일치를 지원하도록 스크립트를 업데이트했습니다.
Wernight

두 문제는 "--monitor"모드에서 inotifywait을 사용하여 해결됩니다. cychoi의 답변을 참조하십시오.
Jonathan Hartley

3

향상된 세바스찬 해결책 watch 명령:

watch_cmd.sh:

#!/bin/bash
WATCH_COMMAND=${1}
COMMAND=${2}

while true; do
  watch -d -g "${WATCH_COMMAND}"
  ${COMMAND}
  sleep 1     # to allow break script by Ctrl+c
done

전화 예 :

watch_cmd.sh "ls -lR /etc/nginx | grep .conf$" "sudo service nginx reload"

작동하지만 조심해야합니다. watch 명령은 버그를 알고있다. (man을 보라) : 터미널 부분에있는 VISIBLE의 변화에만 반응한다. -g CMD 산출.


2

시도해 볼 수 있습니다. 휘어진 .

Reflex는 디렉토리를보고 특정 파일이 변경 될 때 명령을 다시 실행하는 작은 도구입니다. 자동으로 컴파일 / lint / 테스트 작업을 실행하고 코드가 변경되면 응용 프로그램을 다시로드하는 데 적합합니다.

# Rerun make whenever a .c file changes
reflex -r '\.c$' make

이 도구에 대해 약간의 설명을 해줄 수 있습니까? 빨리 읽으십시오. 소프트웨어 추천 방법 안내를 위해.
bertieb

1

파일 변경 사항을 추적하기 위해 사용하고있는 oneliner 응답 :

$ while true ; do NX=`stat -c %Z file` ; [[ $BF != $NX ]] && date >> ~/tmp/fchg && BF=$NX || sleep 2 ; done

첫 번째 날짜가 시작 시간임을 알면 BF를 초기화 할 필요가 없습니다.

이것은 간단하고 이식성이 뛰어납니다. 여기에는 스크립트를 사용하는 동일한 전략을 기반으로하는 또 다른 대답이 있습니다. 또한보십시오.


사용법 : 디버깅하고 계속 지켜 볼 때 사용합니다. ~/.kde/share/config/plasma-desktop-appletsrc; 그 이유는 알 수없는 이유로 SwitchTabsOnHover=false


1

이 스크립트를 사용하여 작업을 수행합니다. 모니터 모드에서 inotify를 사용하고 있습니다.

#!/bin/bash
MONDIR=$(dirname $1)
ARQ=$(basename $1)

inotifywait -mr -e close_write $MONDIR | while read base event file 
do
  if (echo $file |grep -i "$ARQ") ; then
    $1
  fi
done

이것을 runatwrite.sh로 저장하십시오.

Usage: runatwrite.sh myfile.sh

각 쓰기에서 myfile.sh를 실행합니다.


1

OS X을 사용하는 사용자는 LaunchAgent를 사용하여 변경 사항에 대한 경로 / 파일을보고 그럴 때 무언가를 할 수 있습니다. FYI - LaunchControl은 데몬 / 에이전트를 쉽게 만들거나 수정하거나 제거 할 수있는 좋은 응용 프로그램입니다.

( 여기에서 가져온 예 )

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test</string>
    <key>ProgramArguments</key>
    <array>
        <string>say</string>
        <string>yy</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>~/Desktop/</string>
    </array>
</dict>
</plist>


0

검색을 통해이를 찾는 사람들을 위해 특별한 파일에 대한 답변은 훨씬 간단합니다 ( 질의 대답 ).

뭔가하고 싶다면 특정 파일이 작성된 경우 다음을 수행합니다.

while true; do
  inotifywait -e modify /path/to/file
  # Do something *after* a write occurs, e.g. copy the file
  /bin/cp /path/to/file /new/path
done

예를 들어, copy_myfile.sh 그리고 .sh 파일에 /etc/init.d/ 폴더를 시작시 실행할 수 있습니다.


자일즈의 대답에 대한 문제를 모든 반복에서 inotifywait을 실행한다는 점을 알려주며 매우 큰 디렉토리를 재귀 적으로 보는 경우 반응이 없을 수 있습니다. 이것에 대한 해결책은 cychoi의 대답을 참조하십시오.
Jonathan Hartley


0

다른 몇몇 사람들이 한 것처럼, 나는 이것을하기 위해 간단한 명령 행 도구를 작성했다. 완벽하게 문서화되고 테스트되며 모듈 식입니다.

시계도

설치

다음을 사용하여 Python3 및 pip를 설치할 수 있습니다.

pip3 install git+https://github.com/vimist/watch-do

용법

다음을 실행하여 바로 사용하십시오.

watch-do -w my_file -d 'echo %f changed'

기능 개요

  • 파일 globbing 지원 (사용 -w '*.py' 또는 -w '**/*.py' )
  • 파일 변경시 여러 명령 실행 ( -d 다시 플래그)
  • globbing이 사용되면 감시 할 파일 목록을 동적으로 유지 관리합니다. -r 이 기능을 켜려면)
  • 파일을 "보는"여러 가지 방법 :
    • 수정 시간 (기본값)
    • 파일 해시
    • 자신을 구현하는 것이 쉽지 않습니다 (이것은 수정 시간 당직자)
  • 모듈 형 설계. 명령을 실행하려면 파일에 액세스 할 때 자체 관찰자 (행위자를 실행해야하는지 결정하는 메커니즘)를 작성하는 것이 좋습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.