Ada built-in perintah Unix repeat
yang argumen pertamanya adalah berapa kali untuk mengulangi perintah, di mana perintah (dengan argumen apa pun) ditentukan oleh argumen yang tersisa repeat
.
Sebagai contoh,
% repeat 100 echo "I will not automate this punishment."
akan menggema string yang diberikan 100 kali dan kemudian berhenti.
Saya ingin perintah serupa - sebut saja forever
- yang berfungsi sama kecuali argumen pertama adalah jumlah detik untuk jeda di antara pengulangan, dan itu berulang selamanya. Sebagai contoh,
% forever 5 echo "This will get echoed every 5 seconds forever and ever."
Saya pikir saya akan bertanya apakah hal itu ada sebelum saya menulisnya. Saya tahu ini seperti Perl 2-baris atau skrip Python, tapi mungkin ada cara yang lebih standar untuk melakukan ini. Jika tidak, jangan ragu untuk mengirimkan solusi dalam bahasa scripting favorit Anda, gaya Rosetta Stone .
PS: Mungkin cara yang lebih baik untuk melakukan ini adalah dengan menyamaratakan repeat
untuk mengambil jumlah kali untuk mengulangi (dengan -1 yang berarti tak terhingga) dan jumlah detik untuk tidur di antara pengulangan. Contoh di atas kemudian menjadi:
% repeat 100 0 echo "I will not automate this punishment."
% repeat -1 5 echo "This will get echoed every 5 seconds forever."
sumber
type repeat
dan memberi tahu saya dari mana datangnya?repeat
adalah perintah builtin di csh dan tcsh.Jawaban:
Coba
watch
perintahnya.Yang seperti itu:
akan menjalankan perintah setiap detik (well, secara teknis, setiap satu detik ditambah waktu yang diperlukan untuk
command
menjalankan sebagaiwatch
(setidaknyaprocps
danbusybox
implementasi) hanya tidur satu detik di antara dua berjalancommand
), selamanya.Apakah Anda ingin meneruskan perintah
exec
alih-alihsh -c
, gunakan-x
opsi:Di macOS, Anda bisa dapatkan
watch
dari Mac Ports :Atau Anda bisa mendapatkannya dari Homebrew :
sumber
while true; do X; sleep Y; done
- Ini jauh lebih baik.cmdwatch
pada FreeBSD (dari port:)sysutils/cmdwatch
.Pesta
while
+sleep
:Berikut hal yang sama dengan tulisan singkat satu kalimat (Dari komentar di bawah):
Menggunakan
;
untuk memisahkan perintah dan kegunaansleep 1
untukwhile
pengujian karena selalu mengembalikan true. Anda dapat menempatkan lebih banyak perintah dalam loop - cukup pisahkan dengan;
sumber
sleep
tidak selalu kembali benar. Ī̲ menggunakan loop seperti itu (walaupun dengan penundaan lebih lama) yaitu karena ada cara untuk menghentikannya dengan anggun dengan membunuh proses tidur.Ini hanya versi yang lebih pendek dari
while+sleep
jawaban lain , jika Anda menjalankan tugas semacam ini sesering rutinitas harian Anda, menggunakan ini akan menyelamatkan Anda dari penekanan tombol yang tidak perlu, dan jika baris perintah Anda mulai memahami lebih lama, yang ini sedikit lebih mudah. Tapi yang ini dimulai dengan tidur dulu.Ini umumnya berguna jika Anda perlu mengikuti sesuatu yang memiliki output satu baris seperti beban mesin:
sumber
while clear; do date; command;sleep 5; done
while sleep
kombinasinya, simpan keystoke!Satu masalah yang dimiliki oleh semua jawaban yang diposting sejauh ini adalah bahwa waktu perintah dieksekusi dapat melayang. Misalnya, jika Anda melakukan
sleep 10
perintah di antara, dan perintah tersebut membutuhkan waktu 2 detik untuk dijalankan, maka perintah itu akan berjalan setiap 12 detik; jika dibutuhkan jumlah variabel waktu untuk dijalankan, maka dalam jangka panjang waktu ketika itu berjalan tidak dapat diprediksi.Ini mungkin yang Anda inginkan; jika demikian, gunakan salah satu solusi lain, atau gunakan yang ini tetapi sederhanakan
sleep
panggilannya.Untuk resolusi satu menit, tugas cron akan berjalan pada waktu yang ditentukan, terlepas dari berapa lama setiap perintah. (Bahkan pekerjaan cron baru akan diluncurkan bahkan jika yang sebelumnya masih berjalan.)
Berikut ini skrip Perl sederhana yang tertidur hingga interval berikutnya, jadi misalnya dengan interval 10 detik perintah mungkin berjalan pada 12:34:00, 12:34:10, 12:34:20, dll., Bahkan jika Perintah itu sendiri membutuhkan beberapa detik. Jika perintah berjalan lebih dari
interval
detik, interval berikutnya akan dilewati (tidak seperti cron). Interval dihitung relatif terhadap zaman, sehingga interval 86400 detik (1 hari) akan berjalan pada tengah malam UTC.sumber
while :; do sleep 1m & command; wait; done
wait
akan menunggu semuanya). Itu bisa diperbaiki dengan mengubahwait
kewait $!
, di mana$!
PIDsleep
proses. Posting ini sebagai jawaban dan saya akan membatalkannya. Tapi itu memang menghasilkan beberapa output luar dalam shell interaktif.Saya pikir semua jawaban di sini sejauh ini terlalu berbelit-belit, atau sebaliknya menjawab pertanyaan yang berbeda:
Pertanyaan sebenarnya adalah:
Ini adalah dua hal yang sangat berbeda ketika perintah membutuhkan waktu untuk selesai.
Ambil contoh skrip
foo.sh
(pura-pura ini adalah program yang membutuhkan beberapa detik untuk menyelesaikannya).Anda ingin menjalankan ini setiap detik, dan sebagian besar akan menyarankan
watch -n1 ./foo.sh
, atauwhile sleep 1; do ./foo.sh; done
. Namun, ini memberikan output:Yang tidak persis dijalankan setiap detik. Bahkan dengan
-p
flag, seperti yangman watch
disarankan halaman mungkin menyelesaikan ini, hasilnya adalah sama.Cara mudah untuk menyelesaikan tugas yang diinginkan, yang disentuh oleh beberapa orang, adalah menjalankan perintah di latar belakang. Dengan kata lain:
Dan hanya itu yang ada untuk itu.
Anda dapat menjalankannya setiap 500 ms dengan
sleep 0.5
, atau apa pun.sumber
while :; do sleep 1 & ./foo.sh; wait; done
date +"%H:%M:%S.%N"
foo.sh untuk melihat bagaimana fraksi akan meningkat secara perlahan pada setiap loop.Di
bash
:(
echo
dapat diganti dengan perintah apa pun ...Atau di
perl
:Di mana
print "I will not automate this punishment in absurdum.\n"
bisa diganti dengan perintah "any" yang dikelilingi dengan backticks (`).Dan untuk jeda, tambahkan
sleep
pernyataan di dalam for loop:dan
sumber
while [ 0 ]
adalah cara yang buruk untuk menulisnya. Artinya0
adalah string dengan panjang> 0.while [ 1 ]
atauwhile [ jeff ]
akan melakukan hal yang sama. Lebih baik menuliswhile true
.while :
Bash terbaru> = 4.2 di bawah kernel Linux terbaru, berdasarkan jawaban.
Untuk membatasi waktu eksekusi, tidak ada garpu ! Hanya built-in yang digunakan.
Untuk ini, saya menggunakan
read
fungsi builtin bukansleep
. Sayangnya ini tidak akan berfungsi dengan sesi notty .Fungsi bash cepat "
repeat
" seperti yang diminta:Tes kecil dengan string yang dikutip:
Bergantung pada rincian dan durasi perintah yang dikirimkan ...
Di bawah kernel Linux baru-baru ini, ada procfile yang
/proc/timer_list
berisi informasi waktu dalam nanodetik.Jika Anda ingin menjalankan perintah tepat satu detik, perintah Anda harus berakhir kurang dari satu detik! Dan dari sana, Anda
sleep
hanya perlu sisa detik saat ini.Jika penundaan lebih penting dan perintah Anda tidak memerlukan waktu yang signifikan, Anda dapat:
Tetapi jika tujuan Anda adalah untuk mendapatkan rincian yang lebih baik, Anda harus:
Gunakan informasi nanodetik untuk menunggu hingga awal sedetik ...
Untuk ini, saya menulis fungsi bash kecil:
Setelah mengambilnya, Anda dapat:
berjalan
${command[@]}
langsung di baris perintah, dibandingkan denganini harus memberikan hasil yang persis sama.
Rekrut fungsi bash "
repeat
" seperti yang diminta:Anda dapat sumber ini:
Kemudian cobalah:
sumber
read -t
adalah built-in , sedangkansleep
tidak. Ini dapat memiliki efek perbatasan (yaitu memukul [kunci: kembali] mengganggu tidur secara diam-diam ), tetapi ini dapat diobati dengan menguji$foo
Mau coba ini (Bash)?
sumber
repeat
khusus untuk csh dan tcsh.Perl
sumber
Bash dan beberapa kerang sejenisnya memiliki
(( ... ))
notasi yang nyaman di mana ekspresi aritmatika dapat dievaluasi.Jadi sebagai jawaban untuk tantangan ketiga Anda, di mana penghitungan ulang dan penundaan di antara setiap pengulangan harus dapat dikonfigurasi, berikut adalah salah satu cara untuk melakukannya:
Jawaban ini juga mengalami penyimpangan waktu yang tercakup dalam jawaban Keith .
sumber
Seperti disebutkan oleh gbrandt, jika
watch
perintah itu tersedia, pasti gunakan itu. Beberapa sistem Unix, bagaimanapun, tidak menginstalnya secara default (setidaknya mereka tidak di tempat saya bekerja).Inilah solusi lain dengan sintaks dan output yang sedikit berbeda (berfungsi dalam BASH dan SH):
Sunting: Saya menghapus beberapa "." dalam pernyataan gema terakhir ... peninggalan dari hari Perl saya;)
sumber
while [ 1 ]
hanya berfungsi karena 1 diperlakukan sebagai string, sama sepertiwhile [ -n 1 ]
.while [ 0 ]
atauwhile [ jeff ]
akan melakukan hal yang sama.while true
jauh lebih masuk akal.Jika niat Anda untuk tidak menampilkan pesan ke layar Anda, dan jika Anda mampu mengulangi pekerjaan dalam hitungan menit, crontab , mungkin, akan menjadi alat terbaik Anda. Misalnya, jika Anda ingin menjalankan perintah Anda setiap menit, Anda akan menulis sesuatu seperti ini di
crontab
file Anda :Silakan lihat tutorial untuk contoh lebih lanjut. Anda juga dapat mengatur timing dengan mudah menggunakan Crontab Code Generator .
sumber
Bagaimana jika kita memiliki keduanya?
Inilah idenya: dengan hanya "interval", itu berulang selamanya. Dengan "interval" dan "kali", ini mengulangi jumlah kali ini, dipisahkan oleh "interval".
Penggunaan:
Jadi, algoritme akan:
Oleh karena itu:
sumber
sleep
tidak menerimanya.Saya akhirnya menciptakan varian pada jawaban swalog. Dengan itu Anda harus menunggu X detik untuk iterasi pertama, saya juga menjalankan latar depan saya jadi ..
sumber
Cepat, kotor dan mungkin berbahaya untuk boot, tetapi jika Anda petualangan dan tahu apa yang Anda lakukan, menempatkan ini ke dalam
repeat.sh
danchmod 755
itu,Meminta dengan
./repeat.sh <command> <interval>
Perasaan spidey saya mengatakan ini mungkin cara jahat untuk melakukan ini, apakah perasaan spidey saya benar?
sumber
sleep $1; shift; "$@"
atau serupa akan jauh lebih baik.Anda dapat menjalankan skrip dari init (menambahkan baris ke / etc / inittab). Script ini harus menjalankan perintah Anda, tidur untuk waktu yang Anda ingin menunggu sampai menjalankan skrip lagi, dan keluar. Init akan memulai skrip Anda lagi setelah keluar.
sumber
Cara mudah untuk mengulangi pekerjaan dari crontab dengan interval kurang dari satu menit (contoh 20 detik):
crontab: * * * * * script.sh
script.sh:
sumber
Anda bisa mendapatkan kekuatan dari juru bahasa python dari shell.
ganti lima kapan saja (detik) yang kamu suka.
Perhatian: kembali gunakan SHIFT + ENTER untuk mengembalikan input dalam shell. Dan jangan lupa untuk mengetik 4 spasi SPACE di setiap baris sementara loop.
sumber
python
'sos.system()
mengeksekusi shell untuk menafsirkan baris perintah, sehingga memohonpython
untuk menjalankan kerang dalam satu lingkaran untuk menjalankan perintah secara periodik adalah sedikit berlebihan. Anda mungkin juga melakukan semua yang ada di shell.Solusi ini berfungsi di MacOSX 10.7. Ini bekerja dengan sangat baik.
Dalam hal ini
atau
untuk membersihkan desktop saya terus-menerus.
sumber
sleep
perintah di sana?while [ 0 ]
adalah cara yang aneh untuk menulis infinite loop; ini berfungsi karenatest
perintah (juga dikenal sebagai[
) memperlakukan string yang tidak kosong sebagai benar.while : ; do ... ; done
lebih idiomatis, atau jika Anda suka, Anda dapat menggunakanwhile true ; do ... ; done
.Anda bisa mendapatkan fungsi rekursif ini:
atau tambahkan:
dan hubungi skrip.
sumber
Untuk berulang kali menjalankan perintah di jendela konsol, saya biasanya menjalankan sesuatu seperti ini:
while true; do (run command here); done
Ini juga berfungsi untuk banyak perintah, misalnya, untuk menampilkan jam yang terus diperbarui di jendela konsol:
while true; do clear; date; sleep 1; done
sumber
sumber
Dengan
zsh
dansleep
implementasi yang menerima argumen floating-point:Atau untuk
forever
:Jika Anda
sleep
tidak mendukung mengapung, Anda selalu dapat mendefinisikan sebagai pembungkus sekitarzsh
'szselect
builtin:sumber
... Saya ingin tahu berapa banyak solusi rumit yang dapat dibuat saat menyelesaikan masalah ini.
Ini bisa sangat mudah ...
letakkan di sana 1 baris berikutnya ke akhir file seperti:
Jika Anda ingin menjalankan sesuatu setiap 1 detik, cukup letakkan di sana:
dan di dalam file.sh itu harus:
dan itu saja!
NIKMATI!
sumber
bekerja untukku.
sumber