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.