터미널에서 x 간격마다 명령을 반복 하시겠습니까?


142

디렉토리 를 확인 하거나 모니터링 하는 명령을 실행할 수 있도록 간격마다 명령을 어떻게 반복 할 수 있습니까?

스크립트가 필요하지 않습니다. 터미널에서 간단한 명령을 실행하면됩니다.

답변:


219

watch명령 을 사용할 수 있습니다 . watch 는 정기적으로 지정된 명령을 실행하는 데 사용됩니다.

터미널을 열고 다음을 입력하십시오.

watch -n x <your command>

x 를 원하는 시간 (초)으로 변경하십시오 .

watch명령 및 해당 옵션 사용에 대한 자세한 도움말을 man watch보려면이 링크를 실행 하거나 방문하십시오 .

예를 들면 다음과 같습니다 . 다음은 60 초 마다 동일한 터미널에 데스크탑 디렉토리의 내용을 나열하므로 변경 사항이 있는지 알 수 있습니다.

watch -n 60 ls -l ~/Desktop

34
+1이지만 확장 사용시주의하십시오. 예를 들어, 터미널 크기를 조정할 때 watch -n 1 'echo $COLUMNS'watch -n 1 echo $COLUMNS크기를 조정할 때 차이점을 시도하십시오 . 전자는 매 초마다 확장되지만 후자는 시작 하기 전에 한 번만 확장 watch됩니다.
l0b0

그것은 매력처럼 작동합니다! Ty nux

이 솔루션의 문제점은 시계를 프로세스로 실행할 수 없으며 백그라운드에서 실행되도록 두는 것입니다 (예 : & disown)
Cestarian

2
watch"history enabled"type 명령과 함께 사용할 수있는 방법이 있습니까? 나는을 사용 watch하는 것을 좋아하지만 때로는 마지막 실행 대신 이전 실행 로그를보고 싶을 때가 있습니다. 그리고 그렇습니다. 스크립팅 ( while true)을 사용하여이 작업을 수행 할 수 있지만 watch유틸리티를 사용하는 것이 훨씬 깔끔합니다!
rinogo

이것은 간단한 명령에서 작동했지만 파이프 라인 명령 체인에서는 작동하지 않았습니다. 다음은 내가 시도한 명령 => cat api.log | grep '호출'| wc -l
Sudip Bhandari

90

nux의 답변과 별도로 터미널 에서이 명령을 사용할 수도 있습니다.

while true; do <your_command>; sleep <interval_in_seconds>; done

while true; do ls; sleep 2; done

이 명령은 ls2 초 간격으로 출력을 인쇄합니다 .

Ctrl+ C를 사용 하여 프로세스를 중지하십시오.

몇 가지 단점이 있습니다 watch

  • 별명 명령을 사용할 수 없습니다.
  • 명령 출력이 상당히 길면 스크롤이 제대로 작동하지 않습니다.
  • 특정 시간을 초과 하여 최대 시간 간격 을 설정하는 데 문제가 있습니다 .
  • watch-c또는 --color옵션을 사용하여 이스케이프 문자를 전달하는 ANSI 색상 시퀀스를 해석합니다 . 예를 들어의 출력 pygmentize은 작동하지만 실패합니다 ls --color=auto.

위의 상황에서 이것은 더 나은 옵션으로 나타날 수 있습니다.


watch그것을 위해 존재합니다, 이것은 내가 말하고자하는 약간 쓸모가 없습니다
Bruno Pereira

14
이 답변이 처음부터 사용된다고 주장하지는 않습니다. watch대부분의 경우에 좋습니다. 그래서 처음에 "nux의 답변을 제외하고"언급했습니다. 그러나 watch예를 들어에 별명 명령을 사용할 수없는watch 문제는 거의 없습니다 . ll별명이지만와 ls -laF함께 사용할 수없는 예를 들어 보자 watch. 또한 명령의 출력이 너무 길면을 사용하여 스크롤하는 데 문제가 있습니다 watch. 이 특별한 경우에는이 답변이 더 나은 옵션으로 보일 수 있습니다.
souravc

@souravc watch적어도 내 버전은 컬러 출력에 대한 -c또는 --color옵션을 허용합니다 .
Lily Chung

8
while sleep x더 나은-죽이는 것이 더 쉽습니다.
d33tah

3
이것은 좋은 대안이며, 달리 watch, 명령 기록을 유지합니다.
adelriosantiago

34

souravcnux 의 답변 을 듣고 싶었습니다 .

  1. watch우분투에서는 완벽하게 작동 하지만 "Unix-fu"를 순수하게 만들고 싶다면 FreeBSD에서 watch는 "다른 tty 라인을 스누핑"하는 명령입니다.
  2. while true; do command; sleep SECONDS; doneCTR + C를 사용하여 명령을 죽이기가 더 어려울 수도 있습니다 . 당신이 선호 할 수 있습니다 while sleep SECONDS; do command; done- 그것은뿐만 아니라 짧은뿐만 아니라 방해 쉽다. 경고는 먼저 잠자고 명령을 실행한다는 것이므로 명령 SECONDS이 처음 발생하기 전에 약간 기다려야 합니다.

2
의견 대신 답변으로 받아 들일 수 있기를 바랍니다. 여기에 다른 해결책을 제시하고 싶을 때 실제로 의견을 덜주었습니다.
d33tah

루프 sleep에서 어디에 배치 while해야합니까? 나는 차이점을 찾을 수 없었습니다 .Ctrl + C는 즉시 상관없이 루프를 끊었습니다 .
디저트

@dessert : 당신이 생각하는 것에서 벗어나려고하는 것에 달려 있습니다. 일반적으로, Ctrl + C은 당신을 죽일 것입니다 command그리고 sleep당신이 죽일 경우에만 휴식 true.
d33tah

11

cron주기적 명령을 실행할 수 있는 데몬에 이상적인 작업 인 것 같습니다 . crontab -e명령을 실행 하여 사용자의 cron 구성 편집을 시작하십시오. 형식은 crontab (5)에 설명되어 있습니다. 기본적으로 5 개의 시간 관련 공백으로 구분 된 필드와 명령이 있습니다.

The time and date fields are:

       field          allowed values
       -----          --------------
       minute         0-59
       hour           0-23
       day of month   1-31
       month          1-12 (or names, see below)
       day of week    0-7 (0 or 7 is Sunday, or use names)

예를 들어 매주 화요일 오전 11시에 Python 스크립트를 실행하려면 다음을 수행하십시오.

0 11 * * 1 python ~/yourscript.py

와 같이 시간을 대체하는 특수 이름도 있습니다 @reboot. 임시 디렉토리를 작성해야하는 경우 매우 유용합니다. 내 crontab에서 (로 나열 crontab -l) :

# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"

4
이 질문은 터미널에서 주기적으로 무언가를 실행하는 방법을 묻습니다. cron터미널이 아닌 무대 뒤에서 실행
Northern-bradley

5

파일 시스템을 모니터링하는 경우 inotifywait훌륭하고 확실히 시스템에로드를 줄입니다.

예 :

에서 1 터미널이 명령을 입력합니다 :

$ inotifywait .

그런 다음 두 번째 터미널에서 현재 디렉토리에 영향을주는 모든 명령

$ touch newfile

그런 다음 원래 터미널에서 inotifywait가 일어나 이벤트를보고합니다.

./ CREATE newfile2

또는 루프

$ while true ; do inotifywait . ; done
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ DELETE newfile
Setting up watches.  
Watches established.
./ CREATE,ISDIR newdir
Setting up watches.  
Watches established.

사용자가 스크립트를 말하지 않았으며, 아무 것도 모니터링하고 싶지 않다
nux

3
나는 그에게 스크립트를 작성하라고 말하지 않았는데, 그들이 특정 파일 시스템 이벤트를 감시하기 위해 루핑하는 경우 inotifywait가 유용하며 명령을 반복하는 것보다 적은 리소스를 사용한다고 제안했습니다. 나는 종종 명령 줄에서 여러 명령을 실행합니다. 예를 들어 grep something InALogFile|less스크립트입니까?
X Tian

그것의 좋은 대답은, 더 단순 해 보이도록 편집 해보십시오.
nux

3
.내가 명령을 내릴 수없는 것보다 더 간단 할 수있는 것은 무엇입니까?
X Tian

훌륭한 명령 인 @XTian에게 감사합니다. 또한 맨 페이지 -m에서 루프없이 지속적으로 모니터링하기 위해 추가 할 수있는 것을 보았습니다 .
yoniLavi

4

repeat다음 단계를 수행 하여 고유 한 명령을 작성할 수 있습니다 . 여기에 크레딧 :

먼저 .bash_aliases파일을여십시오.

$ xdg-open ~/.bash-aliases

둘째, 파일의 맨 아래에 다음 행을 붙여넣고 저장하십시오.

repeat() {
n=$1
shift
while [ $(( n -= 1 )) -ge 0 ]
do
    "$@"
done
}

셋째, 터미널을 닫았다가 다시 열거 나 다음을 입력하십시오.

$ source ~/.bash_aliases

vo! 이제 다음과 같이 사용할 수 있습니다.

$ repeat 5 echo Hello World !!!

또는

$ repeat 5 ./myscript.sh

xdg-open ~ / .bash-aliases 줄에 작은 오타가 있습니다. xdg-open ~ / .bash_aliases (예 : 밑줄)
ssinfod

4

crontab을 사용할 수 있습니다. 명령을 실행하고 crontab -e원하는 텍스트 편집기로 연 다음이 줄을 추가하십시오.

*/10 * * * *  /path-to-your-command

10 분마다 명령이 실행됩니다.

* */4 * * *  /path-to-your-command

4 시간마다 명령이 실행됩니다.

또 다른 가능한 해결책

$ ..some command...; for i in $(seq X); do $cmd; sleep Y; done

반복 할 X 횟수입니다.

반복 대기하는 Y 시간.

예 :

$ echo; for i in $(seq 5); do $cmd "This is echo number: $i"; sleep 1;done

이것이 왜 개선입니까? 명령을 변수로 저장하여 불필요한 단계를 추가했습니다. 이것이하는 유일한 일은 i) ii를 길게하는 것입니다. ii) 간단한 명령 만 사용하고, 파이프 나 방향 전환 등을 사용하지 않아야합니다.
terdon

추가 변수 제거
Maythux

3

위에서 제안한 "감시"접근 방식의 또 다른 문제는 프로세스가 완료된 경우에만 결과를 표시한다는 것입니다. "date; sleep 58; date"는 59 초 후에 만 ​​2 개의 날짜를 표시합니다. 4 분 동안 실행중인 항목을 시작하면 여러 페이지의 콘텐츠가 느리게 표시되면 실제로 볼 수 없습니다.

반면에 "while"접근 방식은 작업 시간을 고려하지 않습니다.

while true; do script_that_take_between_10s_to_50s.sh; sleep 50; done

이를 통해 스크립트는 1 분마다 실행되며 1m40이 소요될 수 있습니다. 따라서 cron이 1 분마다 실행할 수는 있지만 여기서는 그렇지 않습니다.

따라서 셸에서 출력이 생성 될 때 출력을보고 정확한 요청 시간을 기다리려면 이전과 이후의 시간을 확인하고 while을 반복해야합니다.

다음과 같은 것 :

while ( true ); do
  echo Date starting `date`
  before=`date +%s`
  sleep `echo $(( ( RANDOM % 30 )  + 1 ))`
  echo Before waiting `date`
  after=`date +%s`
  DELAY=`echo "60-($after-$before)" | bc`
  sleep $DELAY
  echo Done waiting `date`
done

이것은 이것을 출력합니다 :

보다시피, 명령은 1 분마다 실행됩니다.

Date starting Mon Dec 14 15:49:34 EST 2015
Before waiting Mon Dec 14 15:49:52 EST 2015
Done waiting Mon Dec 14 15:50:34 EST 2015

Date starting Mon Dec 14 15:50:34 EST 2015
Before waiting Mon Dec 14 15:50:39 EST 2015
Done waiting Mon Dec 14 15:51:34 EST 2015

따라서 "sleep echo $(( ( RANDOM % 30 ) + 1 ))"명령을 원하는 것으로 바꾸면 터미널 / 쉘에서 정확히 1 분마다 실행됩니다. 다른 일정을 원하면 "60"초만 변경하면됩니다.

디버그 라인이없는 짧은 버전 :

while ( true ); do
  before=`date +%s`
  sleep `echo $(( ( RANDOM % 30 )  + 1 ))` # Place you command here
  after=`date +%s`
  DELAY=`echo "60-($after-$before)" | bc`
  sleep $DELAY
done

답장하기 ... 명령이 설정 한 지연 시간보다 오래 걸리면 $ DELAY는 음의 값을 얻게되고 sleep 명령은 실패하므로 스크립트가 즉시 다시 시작됩니다. 알고 있어야합니다.
jmspaggi 2018
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.