Terminaldeki her x aralıkta bir komutu tekrarla?


142

Her zaman aralıklarında bir komutu nasıl tekrar edebilirim , böylece dizinleri kontrol etmek veya izlemek için komutları çalıştırmamı sağlayacak.

Bir betiğe gerek yok, sadece terminalde yürütülecek basit bir komuta ihtiyacım var.

Yanıtlar:


219

watchKomutu kullanabilirsiniz , saatiniz belirlenen komutları düzenli aralıklarla çalıştırmak için kullanılır.

Terminali açın ve yazın:

watch -n x <your command>

x'i istediğiniz saniye cinsinden süre olarak değiştirin .

watchKomutu ve seçeneklerini kullanma konusunda daha fazla yardım için, man watchbu Bağlantıyı çalıştırın veya ziyaret edin .

Örneğin: Aşağıdakiler, her 60'ında , aynı Terminal'de, Desktop dizininin içeriğini listeler; böylece değişiklik olup olmadığını anlayabilirsiniz:

watch -n 60 ls -l ~/Desktop

34
+1, ancak genişleme kullanırken dikkatli olun. Örneğin, terminalinizi yeniden boyutlandırırken watch -n 1 'echo $COLUMNS've arasındaki farkı deneyin watch -n 1 echo $COLUMNS- önceki her saniye genişletilir, ancak ikincisi başlamadan önce yalnızca bir kez genişletilir watch.
l0b0

Mucizevi şekilde çalışır ! Ty nux

Bu çözüm ile ilgili sorun şu ki, bir işlem olarak saatinizi çalıştıramazsınız ve sadece arka planda çalışmaya devam
edemezsiniz

2
watch"Tarih etkin" type komutuyla kullanmanın bir yolu var mı ? Kullanmayı seviyorum watch, ama bazen sadece sonuncusu yerine önceki uygulamaların bir kaydını da görmeyi tercih ederim. Ve evet, bunu yapmak için scripting ( while true) kullanabileceğimi biliyorum , ancak watchfayda kullanmak çok daha temiz!
rinogo

bu, daha basit komutlar için işe yaradı, ancak boru hattı komutları ile zincirleme, bunun benim için işe yaramadı. grep 'çağırıyor' | wc -l
Sudip Bhandari

90

Bu komutu nux'un cevabı dışında terminalde de kullanabilirsiniz:

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

Örnek

while true; do ls; sleep 2; done

Bu komut ls2 saniyelik bir aralıkta çıktı yazdıracaktır .

İşlemi durdurmak için Ctrl+ kullanın C.

Birkaç dezavantajı var watch

  • Herhangi bir takma komut kullanılamaz.
  • Herhangi bir komutun çıktısı oldukça uzunsa, kaydırma düzgün çalışmıyor.
  • Maksimum zaman aralığını belirli bir değerin ötesinde ayarlamakta bazı sorunlar var .
  • watch-cveya --colorseçenek kullanarak kaçış karakterlerini geçen ANSI renk dizilerini yorumlar . Örneğin çıktısı pygmentizeişe yarayacak ama başarısız olacak ls --color=auto.

Yukarıdaki durumlarda bu daha iyi bir seçenek olarak görünebilir.


watchbunun için var, bu söyleyeceğim biraz işe yaramaz
Bruno Pereira

14
Bu cevabı ilk etapta kullanmak olduğunu iddia etmiyorum. watchçoğu durumda iyidir. Bu yüzden başlangıçta "nux'un cevabından ayrı" demiştim. Ancak watch, örneğin bir takma ad komutunu kullanamayanwatch ile ilgili birkaç sorun var . Örneğin ll, takma adı olan ls -laFancak kullanılamayan bir örneği kullanın watch. Ayrıca herhangi bir komutun çıktısının oldukça uzun olması durumunda kaydırma kullanmakta zorlanacaksınız watch. Bu birkaç özel durumda bu cevap daha iyi bir seçenek olarak görünebilir.
souravc

@ souravc Benim sürümü watchen azından renklendirilmiş çıktı için -cveya --colorseçeneklere izin verir .
Lily Chung

8
while sleep xdaha iyi - öldürmek daha kolay.
d33tah

3
Bu güzel bir alternatif ve aksine watch, komut tarihini koruyor.
adelriosantiago

34

Sadece souravc ve nux'un cevaplarına katılmak istedim :

  1. watchUbuntu'da mükemmel bir şekilde çalışacak olsa da, "Unix-fu" nızın saf olmasını istiyorsanız, örneğin FreeBSD'de izlemek istemenizin, örneğin "başka bir tty hattında gözetlemenin" bir komut olduğunu görmekten kaçınmak isteyebilirsiniz.
  2. while true; do command; sleep SECONDS; doneAyrıca bir ihtar var - emrinizi CTR + C kullanarak öldürmek zor olabilir . Tercih etmek isteyebilirsiniz while sleep SECONDS; do command; done- sadece kısa değil, aynı zamanda kesilmesi de kolaydır. Dikkat, ilk önce uyuyacak, sonra komutunuzu çalıştıracaktır, bu yüzden komutun SECONDSilk oluşumu gerçekleşmeden önce biraz beklemeniz gerekir .

2
Umarım bir yorum yerine bir cevap olarak kabul edilebilir - Burada başka bir çözüm göstermek istedim ve yorum yapmak bana daha az dikkat ederdi.
d33tah

Eğer nereye koyduğunuzu Neden tam önemi var sleepiçinde whiledöngü? Hiçbir fark bulamadım, Ctrl + C ne olursa olsun anında döngüyü kırdı .
tatlı

@ tatlı: sanırım ne çıkarmaya çalıştığınıza bağlı. Normalde ctrl + c Tıpkı öldürür commandve sleepve onu öldürmeye keşke kırmak true.
d33tah

11

cronPeriyodik komutların çalıştırılmasına izin veren daemon için ideal görev gibi görünüyor . crontab -eKullanıcınızın cron yapılandırmasını düzenlemeye başlamak için komutu çalıştırın . Formatı crontab (5) ile belgelenmiştir . Temel olarak, zamana bağlı, boşlukla ayrılmış beş alanınız var, ardından bir komut var:

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)

Örneğin, her Salı, 11: 00’de bir Python betiği çalıştırmak istiyorsanız:

0 11 * * 1 python ~/yourscript.py

Zamanın yerini alan bazı özel isimler de var @reboot. Geçici bir dizin oluşturmanız gerekirse çok faydalıdır. Benim crontab itibaren (ile listelenen crontab -l):

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

4
Soru terminalde periyodik olarak bir şeyi nasıl çalıştıracağını sorar. cronterminal yerine sahnelerin arkasından geçiyor
kuzey-bradley 19

5

Dosya sistemini izliyorsanız inotifywait, mükemmeldir ve kesinlikle sisteminize daha az yük ekler.

Örnek :

In 1 terminalde şu komutu yazın:

$ inotifywait .

Sonra 2. terminalde, geçerli dizini etkileyen herhangi bir komut,

$ touch newfile

Sonra orijinal terminalinde inotifywait uyanacak ve olayı bildirecek

./ CREATE newfile2

Veya bir döngü içinde

$ 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.

kullanıcı size, komut dosyası olmadan ve belki de hiçbir şey izlemek istemediğini söyledi
nux

3
Ona bir senaryo yazmasını söylemedim, eğer belirli bir dosya sistemi olayını izlemek için döngü halinde çalışıyorlarsa, inotifywait'in yararlı olduğunu ve bir komutu tekrarlamaktan daha az kaynak kullandığını söyledim. Komut satırında sıklıkla birkaç komut çalıştırıyorum, örneğin grep something InALogFile|lessbu bir komut dosyası mı?
X Tian

onun iyi bir cevap, daha basit görünmesi için düzenlemeye çalışın.
nux

3
.Emri veremediğimden daha basit olan ne olabilir ?
X Tian

Teşekkürler @XTian, ​​harika bir komut. Ayrıca man sayfasında -msürekli bir döngü olmadan sürekli izlemek için ekleyebileceğinizi gördüm .
yoniLavi

4

repeatAşağıdaki adımları uygulayarak kendi komutunuzu oluşturabilirsiniz ; burada kredi :

İlk önce .bash_aliasesdosyanızı açın :

$ xdg-open ~/.bash-aliases

İkinci olarak, bu satırları dosyanın altına yapıştırın ve kaydedin:

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

Üçüncüsü, terminalinizi kapatıp tekrar açın veya şunu yazın:

$ source ~/.bash_aliases

Et voilà! Şimdi bu şekilde kullanabilirsiniz:

$ repeat 5 echo Hello World !!!

veya

$ repeat 5 ./myscript.sh

xdg-open ~ / .bash-aliases satırında küçük bir yazım hatası var. olması gerektiği: xdg-open ~ / .bash_aliases (yani: alt çizgi)
ssinfod

4

crontab'ı kullanabilirsiniz. komutu çalıştırın ve crontab -etercih ettiğiniz metin editörüyle açın, sonra bu satırı ekleyin

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

Bu, her 10 dakikada bir emrinizi verecek

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

Bu her 4 saatte bir emrinizi verecek

Başka bir olası çözüm

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

X tekrarlamak için kaç kez.

Tekrarlamak için bekleyeceğiniz Y zamanı.

Örnek :

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

Bu neden bir gelişmedir? Komutu değişken olarak kaydederek fazladan, gereksiz bir adım eklediniz. Bunu yapan tek şey i)
yazmayı

Ekstra değişkeni kaldırın
Maythux

3

Yukarıda önerilen "izleme" yaklaşımıyla ilgili bir başka endişe, sadece işlem yapıldığında sonucu göstermesidir. "tarih; uyku 58; tarih" 2 tarihi yalnızca 59 saniye sonra gösterecektir ... 4 dakika boyunca çalışan bir şeye başlarsanız, yavaşça birden fazla içerik sayfası görüntülerse, onu gerçekten göremezsiniz.

Öte yandan, "süre" yaklaşımıyla ilgili endişe, görev süresini dikkate almamasıdır.

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

Bununla, senaryo bazen her dakika çalışacak, bazen 1m40 sürebilir. Yani bir cron her dakika onu çalıştırabilecek olsa bile, burada olmayacak.

Bu nedenle, kabuktaki çıktının oluşturulduğu şekliyle görmesi ve tam istek süresini beklemesi için, önce ve sonra zamana bakmanız ve süre ile döngü yapmanız gerekir.

Gibi bir şey:

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

Bu, bunun çıktısını alacaktır:

Gördüğünüz gibi, komut her dakika çalışır:

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

Bu yüzden sadece "sleep echo $(( ( RANDOM % 30 ) + 1 ))" komutunu istediğin şekilde değiştir ve bunun terminal / kabukta tam olarak her dakika çalıştırılacak. Başka bir program istiyorsanız, ihtiyacınız olan şeyle "60" saniyesini değiştirin.

Hata ayıklama çizgileri olmadan daha kısa sürüm:

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

Kendime cevap vermek ... Eğer komutunuz yapılandırdığınız gecikmeden daha fazla sürerse, $ DELAY negatif bir değer alır ve uyku komutu başarısız olur, böylece komut dosyası hemen yeniden başlatılır. Bunun farkında olmak gerekir.
jmspaggi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.