Pregunta ¿Cómo duermo durante un milisegundo en bash o ksh?


dormir es un comando muy popular y podemos comenzar a dormir desde 1 segundo:

# wait one second please 
sleep 1

pero ¿cuál es la alternativa si necesito esperar solo 0.1 segundos o entre 0.1 y 1 segundo?

  • Observación: en Linux o OS X sleep 0.XXX funciona bien, pero en solaris sleep 0.1 o sleep 0.01 - sintaxis ilegal

105
2018-01-15 13:19


origen


¿Puedo preguntar por qué quieres dormir 1ms? - Tom O'Connor
Sí, por supuesto, en mi script de bash agrego "sleep 1", en algunas líneas, pero el script se ejecuta muy lentamente, por lo que, después de alguna conclusión, calculo que el sleep 0.1 también brinda buenos resultados y es más rápido. para resolver el problema de ssh en mi script de bash, realizo un inicio de sesión paralelo de ssh en algunas máquinas esperando y sin demora no funcionará. Como saben por mi pregunta, la demora debería corresponder tanto a Linux como a Solaris - yael
Sea cual sea la solución que elija, tenga en cuenta que un script de shell no será muy preciso en términos de tiempo. - scai
¿Qué tal hacer algo que toma muy poco tiempo para ejecutarse, pero no hace nada ... como echo "" >/dev/null - Tom O'Connor
Buena idea pero como msec toma este comando? , Necesito 0.1 ms, no menos que - :) - yael


Respuestas:


Bash tiene un sueño "cargable" que admite segundos fraccionarios y elimina los gastos generales de un comando externo:

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

Entonces:

$ 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

El inconveniente es que los bienes no pueden ser provistos con su bash binario, por lo que debería compilarlos usted mismo como se muestra (aunque en Solaris no necesariamente sería tan simple como el anterior).

A partir de bash-4.4 (Septiembre de 2016), todos los elementos cargables ahora se crean e instalan de manera predeterminada en plataformas que lo admiten, aunque se crean como archivos de objetos compartidos separados, y sin un .so sufijo. A menos que su distribución / sistema operativo haya hecho algo creativo, debería poder hacer lo siguiente:

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

(La página de manual implica BASH_LOADABLES_PATH se establece automáticamente, me parece que este no es el caso en la distribución oficial a partir de 4.4.12. Si y cuando se configura correctamente solo necesita enable -f filename commandname según sea necesario.)

Si eso no es adecuado, la siguiente cosa más fácil de hacer es construir u obtener sleep de GNU coreutils, esto soporta la característica requerida. El posix sleep El comando es mínimo, las versiones anteriores de Solaris implementaron solo eso. Solaris 11 sleep  hace apoyo fraccionaria segundos.

Como último recurso podría utilizar perl (o cualquier otro script que tenga a mano) con la advertencia de que la inicialización del intérprete puede ser comparable al tiempo de espera previsto:

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

59
2018-01-15 13:52



Ah, ya que estás usando expect probablemente solo puedas usar "after N", donde N es milisegundos, directamente en su script. - mr.spuratic
utilizar usleep como @Luis Vazquez y @sebix escriben - Ilan.K


La documentación para el sleep comando de coreutils dice:

Las implementaciones históricas del sueño han requerido que el número sea un   entero, y solo aceptó un solo argumento sin sufijo.   Sin embargo, el modo de espera GNU acepta números de punto flotante arbitrarios. Ver    Punto flotante.

Por lo tanto puedes usar sleep 0.1, sleep 1.0e-1 y argumentos similares.


103
2018-01-15 13:22



ver mi comentario sobre el sistema operativo SOLARIS - yael
Te confundiste es y no es? - scai
ver mi actualización en mi quastion - yael
Yael, creo que todavía hay demasiados aspectos negativos en tu pregunta; ¿estás seguro de que quieres decir "sintaxis no ilegal"? - MadHatter
por ejemplo, ejecuto en solaris 10 esto: # sleep 0.1 sleep: mal carácter en el argumento, sobre linux sleep 0.1 funciona bien - yael


Sleep acepta números decimales para que puedas descomponerlo así:

1/2 de segundo

 sleep 0.5

1/100 de segundo

sleep 0.01

Así que por un milisegundo querrías

sleep 0.001

46
2018-01-15 13:24



También puede soltar el cero inicial antes del punto decimal. p.ej. sleep .5 - Mike Causer
Excepto por mathforum.org/library/drmath/view/52352.html - stark
Habla de todos los demás que lo complican ... - Martin


Intenta esto para determinar la precisión:

    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)

Combinación de solución de mr.spuratic y solución de coles.


11
2018-06-22 19:52





Usted puede simplemente utilizar usleep. Toma microsegundos (= 1e-6 segundos) como parámetro, por lo que para dormir 1 milisegundo ingresaría:

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
No me refiero usleep parte de initscripts paquete que es estándar al menos en todas las distribuciones derivadas de Red Hat; incluyendo al menos RHEL, CentOS, Fedora, Mageia / Mandriva y SuSE. Aquí un ejemplo: `` `` - Luis Vazquez
Aquí hay una ilustración de ejemplo que se ejecuta en CentOS 7: `` `$ que usleep / usr / bin / usleep $ rpm -qf / usr / bin / usleep initscripts-9.49.37-1.el7_3.1.x86_64` `` Para resumir : - sleep (desde coreutils) trabaja con segundos - usleep (desde initscripts) trabaja con microsegundos - Luis Vazquez


Tuve el mismo problema (no shell usleep en Solaris), así que escribí el mío así:

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

No revisa los argumentos: recomendaría uno escrito correctamente si quisiera mantenerlo, pero eso (gcc usleep.c -o usleep) lo sacará de un agujero.


3
2018-05-24 15:12



Tú podrías al menos cambiar eso desnudo usleep() llamar a if(argc == 1) { usleep(atoi(argv[1])); } para evitar la indexación fuera de los límites de la matriz, lo que puede llevar a cualquier número de comportamientos inesperados. - α CVn