Bir milisaniyede bash veya ksh cinsinden nasıl uyurum


128

uyku çok popüler bir komuttur ve uykuya 1 saniyeden başlayabiliriz:

# wait one second please 
sleep 1

peki ancak alternatif olarak yalnızca 0,1 saniye veya 0,1 ila 1 saniye beklemem gerekiyorsa?

  • Not: Linux veya OS X sleep 0.XXXüzerinde iyi çalışıyor, ama solaris sleep 0.1veya sleep 0.01- yasadışı sözdizimi

2
Neden 1ms uyumak istediğini sorabilir miyim?
Tom O'Connor,

1
Evet, elbette, bash betiğimde bazı satırlara "uyku 1" ekliyorum, ancak komut dosyası çok yavaş çalışıyor, bu yüzden bazı sonuçlardan sonra o uykunun 0,1'ini de iyi sonuçlar getirdiğini ve daha hızlı getirdiğini hesaplıyorum. bash betiğimdeki ssh problemini çözmek için bazı makinelere beklendiği gibi beklemeden ve gecikmeden paralel ssh girişi yapıyorum, işe yaramayacak,
sorumdan

3
Hangi çözümü seçerseniz seçin, bir kabuk betiğinin zamanlama açısından çok doğru olmayacağını unutmayın.
scai,

Nasıl yürütmek için çok kısa bir zaman alır, ama hiçbir şey yapmaz şey yapmayı .. gibiecho "" >/dev/null
Tom O'Connor

İyi fikir ama bu komutun ne kadar sürdüğü? , 0.1 msn lazım, o kadar az değil - :)
yael

Yanıtlar:


68

Bash, kesirli saniyeleri destekleyen ve harici bir komutun genel giderlerini ortadan kaldıran "yüklenebilir" bir uyuma sahiptir:

$ cd bash-3.2.48/examples/loadables
$ make sleep && mv sleep sleep.so
$ enable -f sleep.so sleep

Sonra:

$ which sleep
/usr/bin/sleep
$ builtin sleep
sleep: usage: sleep seconds[.fraction]
$ time (for f in `seq 1 10`; do builtin sleep 0.1; done)
real    0m1.000s
user    0m0.004s
sys     0m0.004s

Dezavantajı, yüklerin bashikili sisteminizle sağlanamayabileceğidir , bu yüzden bunları gösterildiği gibi kendiniz derlemeniz gerekir (Solaris'te yukarıdaki kadar basit olması gerekmez).

İtibariylebash-4.4 (Eylül 2016) tüm loadables şimdi inşa edilir ve bunlar ayrı paylaşılan nesne dosyaları olarak inşa edilmiş olsa da, bunu destekleyecek platformlarda varsayılan olarak yüklü ve olmadan .soson eki. Dağıtımınız / işletim sisteminiz yaratıcı bir şey yapmadıysa, bunun yerine şunları yapmalısınız:

[ -z "$BASH_LOADABLES_PATH" ] &&
  BASH_LOADABLES_PATH=$(pkg-config bash --variable=loadablesdir 2>/dev/null)  
enable -f sleep sleep

(Man sayfasının ima ettiği BASH_LOADABLES_PATHotomatik olarak ayarlanır, bunun resmi dağıtımda 4.4.12 itibariyle geçerli olmadığını buldum. Doğru ayarlanmışsa ve sadece enable -f filename commandnamegerektiği gibi yapmanız gerekir .)

Bu uygun değilse, yapılacak en kolay şey sleepGNU coreutils'ten derlemek veya elde etmek , istenen özelliği destekler. POSIX sleepkomutu minimaldir, sadece eski Solaris sürümleri uygulanır. Solaris 11 sleep , kesirli saniyeleri destekler.

Son çare olarak perl, tercümanı başlatan amaçlanan uyku süresiyle karşılaştırılabilir olabilecek ihtar ile (ya da kullanmanız gereken herhangi bir komut dosyasını) kullanabilirsiniz.

$ perl -e "select(undef,undef,undef,0.1);"
$ echo "after 100" | tclsh

2
Ah, kullandığınız expectiçin muhtemelen sadece " after N" N kullanabilirsiniz , burada N milisaniyedir, doğrudan betiğinizde.
mr.spuratic

usleep@Luis Vazquez ve @sebix yazma gibi kullanın
Ilan.K

Apple MacOS, kesirli saniyeleri de destekleyen BSD uykusuna sahip
roblogic

125

Coreutilssleep komutunun dokümantasyonu şöyle diyor:

Uykunun tarihsel uygulamaları, bu sayının bir tamsayı olmasını gerektirdi ve sonek olmadan sadece tek bir argümanı kabul etti. Ancak, GNU uykusu keyfi kayan nokta sayılarını kabul eder. Kayan noktaya bakınız .

Dolayısıyla kullanabileceğiniz sleep 0.1, sleep 1.0e-1ve benzeri argümanları.


1
SOLARIS OS hakkında
yorumumu gör

Eğer karıştırmak mı olduğu ve olmadığı ?
scai

güncellememi quastion'da gör
yael

1
Yael, sanırım sorunuzda hala çok fazla olumsuz var; "yasadışı sözdizimi değil" demek istediğinize emin misiniz?
MadHatter

örneğin - solaris 10'da koşuyorum: # uyku 0.1 uyku: tartışmada kötü karakter, linux uyku hakkında 0.1 iyi çalışıyor
yael

58

Uyku, ondalık sayıları kabul eder;

Saniyenin 1 / 2'si

 sleep 0.5

Saniyenin 1/100

sleep 0.01

Yani bir milisaniye için istersiniz

sleep 0.001

4
Baştaki sıfırı ondalık noktadan önce de bırakabilirsiniz. Örneğin. sleep .5
Mike Causer,


Şaşırtan diğer herkes hakkında konuşun ...
Martin

1
@MikeCauser önde gelen sıfırlar çok daha okunabilir ve kodun okuyucusuna daha sonra niyet etme sinyalleri. Aslında matematik yaptığınızda da daha iyi.
Alexander Mills,


8

Sadece kullanabilirsiniz usleep. Parametre olarak mikrosaniye (= 1e-6 saniye) alır, girdiğiniz 1 milisaniyede uyumak için:

usleep 1000

1
$ usleep No command 'usleep' found, did you mean: Command 'sleep' from package 'coreutils' (main) usleep: command not found
Bulletmagnet

Hayır, en azından Red Hat kaynaklı dağıtımlarda standart usleepolan initscriptspaketin bir kısmını kastediyorum ; en az RHEL, CentOS, Fedora, Mageia / Mandriva ve SuSE dahil. İşte bir örnek: `` ``
Luis Vazquez,

1
İşte CentOS 7'de çalışan örnek bir iptali: `` `$ olan / usr / bin / usleep $ rpm $ / qf / usr / bin / usleep initscripts-9.49.37-1.el7_3.1.x86_64 : - sleep( coreutils'ten ) saniye ile çalışır - usleep( initscripts'den ) mikro saniye ile çalışır
Luis Vazquez

4

Ben de aynı problemi yaşadım (Solaris'te deniz kabuğu yok) bu yüzden kendimi yazdım:

  #include "stdio.h"
  int main(int argc, char **argv) {
     if(argc == 2) { usleep(atoi(argv[1])); }
     return 0;
}

Argümanları kontrol etmez - Eğer saklamak istersen düzgün yazılmış bir tane öneririm ama bu (gcc usleep.c -o usleep) seni bir delikten çıkaracak.


1
Sen olabilir , en azından değişim çıplak olduğu usleep()çağrı için if(argc == 1) { usleep(atoi(argv[1])); }beklenmedik davranışlar herhangi bir sayıda yol açabilir dizisinin sınırları dışındaki, indeksleme önlemek için.
CVn

@aCVn Bu aslında if (argc == 2) { usleep(atoi(argv[1])); }...
Ring Ø

Ayrıca usleepünitenin iss olduğuna dikkat edin , bu nedenle 1 saniye beklemek için 1000000 argümanı sağlamanız gerekir.
Ring Ø

@ RingØ Sağ. Aptal hata, iyi yakalama.
CVn

atoi()bir dize bir dönüştürmek için korkunç bir seçimdir int. Ne atoi( "STRING" )geri döner? atoi()hata döndürmek için hiçbir yolu yoktur.
Andrew Henle

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.