Vraag Hoe slaap ik een milliseconde in bash of ksh


slaap is een erg populaire opdracht en we kunnen vanaf 1 seconde beginnen met slapen:

# wait one second please 
sleep 1

maar wat is het alternatief als ik slechts 0,1 seconde of tussen 0,1 tot 1 seconde moet wachten?

  • opmerking: op linux of OS X sleep 0.XXX werkt prima, maar op solaris sleep 0.1 of sleep 0.01 - illegale syntaxis

105
2018-01-15 13:19


oorsprong


Mag ik vragen waarom je 1ms wilt slapen? - Tom O'Connor
Ja natuurlijk, in mijn bash-script voeg ik "slaap 1" toe, in sommige regels, maar het script loopt erg langzaam, dus na wat conclusie bereken ik dat slaap 0.1 ook goede resultaten en sneller oplevert. Over de vertraging heb ik vertraging nodig om het ssh-probleem op te lossen in mijn bash-script, voer ik paralel ssh-login uit op sommige machines door te verwachten dat het zonder vertraging zal werken. Zoals je weet op mijn vraag, zou de vertraging zowel Linux als Solaris moeten zijn - yael
Welke oplossing u ook kiest, houd er rekening mee dat een shellscript niet erg nauwkeurig zal zijn in termen van timing. - scai
Wat dacht je van iets doen dat een zeer korte tijd kost om uit te voeren, maar niets doet .. zoals echo "" >/dev/null - Tom O'Connor
Goed idee, maar hoe neem je deze opdracht? , Ik heb 0.1 msec nodig, niet minder dan dat - :) - yael


antwoorden:


Bash heeft een "laadbare" slaap die fractionele seconden ondersteunt, en elimineert overheadkosten van een extern commando:

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

Dan:

$ 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

Het nadeel is dat de laadbaarheden mogelijk niet worden geleverd met uw bash binair, dus je zou ze zelf moeten compileren zoals getoond (hoewel het op Solaris niet zo eenvoudig zou zijn als hierboven).

Vanaf bash-4.4 (September 2016) alle loadables zijn nu standaard gebouwd en geïnstalleerd op platforms die dit ondersteunen, hoewel ze zijn gebouwd als afzonderlijke shared-object-bestanden en zonder een .so achtervoegsel. Tenzij je distro / OS iets creatiefs heeft gedaan, zou je in plaats daarvan moeten kunnen doen:

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

(De man-pagina impliceert BASH_LOADABLES_PATH wordt automatisch ingesteld, ik merk dat dit niet het geval is in de officiële distributie vanaf 4.4.12. Als en wanneer het correct is ingesteld, hoeft u alleen maar enable -f filename commandname zoals gevraagd.)

Als dat niet geschikt is, is het eenvoudigst om te bouwen of te verkrijgen sleep van GNU coreutils ondersteunt dit de vereiste functie. De POSIX sleep opdracht is minimaal, oudere versies van Solaris implementeerden alleen dat. Solaris 11 sleep  doet ondersteuning voor fractionele seconden.

Als laatste redmiddel zou je kunnen gebruiken perl (of een andere scripting die u bij de hand hebt) met de waarschuwing dat het initialiseren van de interpreter vergelijkbaar is met de beoogde slaaptijd:

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

59
2018-01-15 13:52



Ah, omdat je gebruikt expect je kunt waarschijnlijk gewoon gebruiken "after N", waarbij N milliseconden is, rechtstreeks in uw script. - mr.spuratic
gebruik usleep zoals @Luis Vazquez en @sebix schrijven - Ilan.K


De documentatie voor de sleep commando van coreutils zegt:

Historische implementaties van slaap vereisten dat dat aantal een is   geheel getal en accepteerde alleen een enkel argument zonder een achtervoegsel.   GNU-slaap accepteert echter willekeurige getallen met drijvende komma. Zien    Drijvend punt.

Vandaar dat je kunt gebruiken sleep 0.1, sleep 1.0e-1 en vergelijkbare argumenten.


103
2018-01-15 13:22



zie mijn opmerking over SOLARIS OS - yael
Heb je het verwisseld is en is niet? - scai
zie mijn update in mijn quastion - yael
Yael, ik denk dat er nog steeds een teveel aan negatieven in je vraag zijn; ben je zeker dat je bedoelt "geen illegale syntaxis"? - MadHatter
bijvoorbeeld - ik loop op solaris 10 dit: # slaap 0.1 slaap: slecht karakter in argument, over linux slaap 0.1 werkt prima - yael


Slaap accepteert decimale getallen, zodat u dit kunt opsplitsen zoals:

1/2 van een seconde

 sleep 0.5

1/100 van een seconde

sleep 0.01

Dus voor een milliseconde zou je willen

sleep 0.001

46
2018-01-15 13:24



U kunt ook de eerste nul vóór de komma laten vallen. bv. sleep .5 - Mike Causer
Behalve voor mathforum.org/library/drmath/view/52352.html - stark
Praat over iedereen die het te ingewikkeld maakt ... - Martin


Probeer dit om de nauwkeurigheid te bepalen:

    time sleep 0.5      # 500 milliseconds (1/2 of a second)
    time sleep 0.001    # 1 millisecond (1/1000 of a second)
    time sleep 1.0      # 1 second (1000 milliseconds)

Combinatie van de oplossing van mr.spuratic en de oplossing van Coles.


11
2018-06-22 19:52





Je kunt het gewoon gebruiken usleep. Het kost microseconden (= 1e-6 seconden) als parameter, dus om 1 milliseconde te slapen zou je het volgende invoeren:

usleep 1000

6
2017-07-08 13:55



$ usleep  No command 'usleep' found, did you mean:  Command 'sleep' from package 'coreutils' (main)  usleep: command not found - Bulletmagnet
Nee ik bedoel usleep deel van de initscripts pakket dat standaard is, althans in alle Red Hat-afgeleide distributies; inclusief ten minste RHEL, CentOS, Fedora, Mageia / Mandriva en SuSE. Hier een voorbeeld: `` `` - Luis Vazquez
Hier is een voorbeeld ilustration in CentOS 7: `` `$ die usleep / usr / bin / usleep $ rpm -qf / usr / bin / usleep initscripts-9.49.37-1.el7_3.1.x86_64` `` Samenvattend : - sleep (van coreutils) werkt met seconden - usleep (van initscripts) werkt met microseconden - Luis Vazquez


Ik had hetzelfde probleem (geen shell slaap op Solaris) dus ik schreef mijn eigen dus:

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

Controleert argumenten niet - ik zou een goed geschreven bericht aanraden als je het wilde behouden, maar dat (gcc usleep.c -o doorslapen) je uit een gat haalt.


3
2018-05-24 15:12



Je zou kunnen tenminste verander dat kaal usleep() bellen naar if(argc == 1) { usleep(atoi(argv[1])); } om indexering buiten de grenzen van de array te vermijden, wat kan leiden tot een willekeurig aantal onverwachte gedragingen. - α CVn