Hay un comando incorporado de Unix repeat
cuyo primer argumento es la cantidad de veces que se repite un comando, donde el comando (con cualquier argumento) se especifica mediante los argumentos restantes repeat
.
Por ejemplo,
% repeat 100 echo "I will not automate this punishment."
hará eco de la cadena dada 100 veces y luego se detendrá.
Me gustaría un comando similar, llamémoslo, forever
que funcione de manera similar, excepto que el primer argumento es el número de segundos para pausar entre repeticiones, y se repite para siempre. Por ejemplo,
% forever 5 echo "This will get echoed every 5 seconds forever and ever."
Pensé en preguntar si existe tal cosa antes de escribirla. Sé que es como un script Perl o Python de 2 líneas, pero tal vez haya una forma más estándar de hacerlo. Si no es así, no dude en publicar una solución en su lenguaje de secuencias de comandos favorito, al estilo de Rosetta Stone .
PD: Quizás una mejor manera de hacer esto sería generalizar repeat
para tomar tanto el número de veces que se repite (con -1 que significa infinito) como el número de segundos para dormir entre repeticiones. Los ejemplos anteriores se convertirían en:
% repeat 100 0 echo "I will not automate this punishment."
% repeat -1 5 echo "This will get echoed every 5 seconds forever."
fuente
type repeat
y decirme de dónde viene?repeat
es un comando incorporado en csh y tcsh.Respuestas:
Prueba el
watch
comando.Así que eso:
ejecutará el comando cada segundo (bueno, técnicamente, cada segundo más el tiempo que tarda
command
en ejecutarse ya quewatch
(al menos las implementacionesprocps
ybusybox
) solo duerme un segundo entre dos ejecuciones decommand
), para siempre.¿Desea pasar el comando a en
exec
lugar desh -c
usar la-x
opción:En macOS, puede obtener
watch
desde puertos Mac :O puede obtenerlo de Homebrew :
fuente
while true; do X; sleep Y; done
. Esto es mucho mejor.cmdwatch
en FreeBSD (desde los puertos:)sysutils/cmdwatch
.Golpetazo
while
+sleep
:Esto es lo mismo que una línea abreviada (De los comentarios a continuación):
Se utiliza
;
para separar comandos y usossleep 1
para lawhile
prueba, ya que siempre devuelve verdadero. Puede poner más comandos en el bucle, solo sepárelos con;
fuente
sleep
no siempre es cierto. Ī̲ usé dichos bucles (aunque con un retraso mayor), principalmente porque hay una manera de terminarlo con gracia matando el proceso de sueño.Esta es solo una versión más corta de otras
while+sleep
respuestas, si está ejecutando este tipo de tareas a menudo como su rutina diaria, usar esto lo salva de presionar teclas innecesarias, y si su línea de comando comienza a ser más larga, comprender esto es un poco más fácil. Pero este comienza con dormir primero.Esto generalmente es útil si necesita seguir algo que tiene una salida de una línea como la carga de la máquina:
fuente
while clear; do date; command;sleep 5; done
while sleep
combinación, ahorra keytokes!Un problema que tienen todas las respuestas publicadas hasta ahora es que el tiempo de ejecución del comando puede derivar. Por ejemplo, si realiza un
sleep 10
comando entre comandos y el comando tarda 2 segundos en ejecutarse, se ejecutará cada 12 segundos; si tarda una cantidad variable de tiempo en ejecutarse, a largo plazo el tiempo en que se ejecuta puede ser impredecible.Esto podría ser justo lo que quieres; si es así, use una de las otras soluciones, o use esta pero simplifique la
sleep
llamada.Para una resolución de un minuto, los trabajos cron se ejecutarán a la hora especificada, independientemente de cuánto tiempo tome cada comando. (De hecho, se iniciará un nuevo trabajo cron incluso si el anterior todavía se está ejecutando).
Aquí hay una secuencia de comandos Perl simple que duerme hasta el siguiente intervalo, por ejemplo, con un intervalo de 10 segundos, el comando podría ejecutarse a las 12:34:00, 12:34:10, 12:34:20, etc., incluso si el El comando en sí toma varios segundos. Si el comando se ejecuta más de
interval
segundos, se omitirá el siguiente intervalo (a diferencia de cron). El intervalo se calcula en relación con la época, por lo que se ejecutará un intervalo de 86400 segundos (1 día) a la medianoche UTC.fuente
while :; do sleep 1m & command; wait; done
wait
los esperará a todos). Eso se puede solucionar cambiandowait
await $!
, dónde$!
está el PID delsleep
proceso. Publique esto como respuesta y lo votaré. Pero sí produce una salida extraña en un shell interactivo.Creo que todas las respuestas aquí hasta ahora son demasiado complicadas, o en su lugar responden una pregunta diferente:
La verdadera pregunta era:
Estas son dos cosas muy diferentes cuando el comando tarda en terminar.
Tomemos como ejemplo el script
foo.sh
(imagine que este es un programa que demora unos segundos en completarse).Desea ejecutar esto cada segundo, y la mayoría sugeriría
watch -n1 ./foo.sh
, owhile sleep 1; do ./foo.sh; done
. Sin embargo, esto da la salida:Que no se ejecuta exactamente cada segundo. Incluso con la
-p
bandera, comoman watch
sugiere la página podría resolver esto, el resultado es el mismo.Una manera fácil de lograr la tarea deseada, que algunos tocan, es ejecutar el comando en segundo plano. En otras palabras:
Y eso es todo lo que hay que hacer.
Podrías ejecutarlo cada 500 ms con
sleep 0.5
, o lo que tengas.fuente
while :; do sleep 1 & ./foo.sh; wait; done
date +"%H:%M:%S.%N"
en foo.sh para ver cómo la fracción aumentará lentamente en cada ciclo.En
bash
:(
echo
podría ser reemplazado por cualquier comando ...O en
perl
:Donde
print "I will not automate this punishment in absurdum.\n"
podría ser reemplazado con "cualquier" comando rodeado de backticks (`).Y para una pausa, agregue una
sleep
declaración dentro del ciclo for:y
fuente
while [ 0 ]
Es una mala forma de escribirlo. Significa que0
es una cadena con longitud> 0.while [ 1 ]
owhile [ jeff ]
haría lo mismo. Mejor escribirwhile true
.while :
Recent bash> = 4.2 bajo el núcleo reciente de Linux, respuesta basada.
Para limitar el tiempo de ejecución, ¡no hay horquillas ! Solo se utilizan incorporados.
Para esto, uso la
read
función incorporada en lugar desleep
. Desafortunadamente, esto no funcionará con sesiones notorias .Función de bash rápida "
repeat
" según lo solicitado:Pequeña prueba con cadenas citadas:
Dependiendo de la granularidad y la duración del comando enviado ...
Bajo los últimos núcleos de Linux, hay un archivo de perfil que
/proc/timer_list
contiene información de tiempo en nanosegundos.Si desea ejecutar un comando exactamente una vez por segundo, ¡su comando debe terminar en menos de un segundo! Y a partir de ahí,
sleep
solo tienes el resto del segundo actual.Si la demora es más importante y su comando no requiere un tiempo significativo, podría:
Pero si su objetivo es obtener una granularidad más fina, debe:
Use la información de nanosegundos para esperar hasta el comienzo de un segundo ...
Para esto, escribí una pequeña función bash:
Después de buscarlos, podrías:
ejecutar
${command[@]}
directamente en la línea de comando, que comparar conEsto debe dar exactamente el mismo resultado.
Contrata la función bash "
repeat
" según lo solicitado:Podrías obtener esto:
Entonces pruébalo:
fuente
read -t
es un incorporado , mientrassleep
que no lo es. Esto podría tener un efecto de borde (es decir, presionar [tecla: retorno] interrumpir silenciosamente el sueño ), pero esto podría tratarse mediante pruebas$foo
¿Te gustaría probar esto (Bash)?
fuente
repeat
es específico de csh y tcsh.Perl
fuente
Bash y algunos de sus shells afines tienen la conveniente
(( ... ))
notación en la que se pueden evaluar las expresiones aritméticas.Entonces, como respuesta a su tercer desafío, donde tanto el recuento de repeticiones como el retraso entre cada repetición deben ser configurables, aquí hay una forma de hacerlo:
Esta respuesta también sufre la deriva de tiempo cubierta en la respuesta de Keith .
fuente
Como mencionó gbrandt, si el
watch
comando está disponible, definitivamente úselo . Sin embargo, algunos sistemas Unix no lo tienen instalado de manera predeterminada (al menos no donde yo trabajo).Aquí hay otra solución con una sintaxis y salida ligeramente diferentes (funciona en BASH y SH):
Editar: eliminé algunos "." en la última declaración de eco ... remanente de mis días en Perl;)
fuente
while [ 1 ]
solo funciona porque 1 se trata como una cadena, al igual quewhile [ -n 1 ]
.while [ 0 ]
owhile [ jeff ]
haría lo mismo.while true
Tiene mucho más sentido.Si su intención no es mostrar un mensaje en su pantalla, y si pudiera permitirse el lujo de repetir el trabajo en términos de minutos, crontab , tal vez, sería su mejor herramienta. Por ejemplo, si desea ejecutar su comando cada minuto, escribiría algo como esto en su
crontab
archivo:Consulte el tutorial para obtener más ejemplos. Además, puede configurar los tiempos fácilmente usando Crontab Code Generator .
fuente
¿Y si tuviéramos los dos?
Aquí está la idea: con solo "intervalo", se repite para siempre. Con "intervalo" y "tiempos", se repite este número de veces, separados por "intervalo".
El uso :
Entonces, el algoritmo será:
Por lo tanto :
fuente
sleep
que los acepta.Terminé creando una variante en la respuesta de swalog. Con la suya, tuvo que esperar X segundos para la primera iteración, también estoy ejecutando mi en primer plano, así que ...
fuente
Rápido, sucio y probablemente peligroso para arrancar, pero si eres aventurero y sabes lo que estás haciendo, pon esto
repeat.sh
ychmod 755
todo,Invocarlo con
./repeat.sh <command> <interval>
Mi sentido de la araña dice que esta es probablemente una forma malvada de hacer esto, ¿es cierto mi sentido de la araña?
fuente
sleep $1; shift; "$@"
o similar sería mucho mejor.Puede ejecutar un script desde init (agregando una línea a / etc / inittab). Este script debe ejecutar su comando, dormir durante el tiempo que desea esperar hasta ejecutar el script nuevamente y salir de él. Init iniciará su script nuevamente después de salir.
fuente
Manera fácil de repetir un trabajo desde crontab con un intervalo de menos de un minuto (ejemplo de 20 segundos):
crontab: * * * * * script.sh
script.sh:
fuente
Puede obtener el poder del intérprete de python desde shell.
reemplace cinco en cualquier momento (seg) que desee.
Atención: la devolución usa MAYÚS + ENTRAR para devolver la entrada en el shell. Y no olvide escribir 4 sangría de ESPACIO en cada línea en el ciclo while.
fuente
python
'sos.system()
ejecuta un shell para interpretar la línea de comandos, por lo que invocapython
para ejecutar las cáscaras en un bucle para ejecutar un comando es un poco exagerado periódicamente. También podrías hacer todo en el shell.Esta solución funciona en MacOSX 10.7. Funciona maravillosamente
En mi caso
o
para limpiar mi escritorio constantemente.
fuente
sleep
comando allí?while [ 0 ]
es una forma extraña de escribir un bucle infinito; funciona porque eltest
comando (también conocido como[
) trata una cadena no vacía como verdadera.while : ; do ... ; done
es más idiomático, o si lo prefieres puedes usarlowhile true ; do ... ; done
.Puede obtener esta función recursiva:
o agregue un:
y llama al guión.
fuente
Para ejecutar repetidamente un comando en una ventana de consola, generalmente ejecuto algo como esto:
while true; do (run command here); done
Esto también funciona para múltiples comandos, por ejemplo, para mostrar un reloj que se actualiza continuamente en una ventana de consola:
while true; do clear; date; sleep 1; done
fuente
fuente
Con
zsh
y unasleep
implementación que acepta argumentos de punto flotante:O para
forever
:Si su
sleep
no admite flotadores, siempre puede redefinirlo como una envoltura alrededorzsh
de lazselect
construcción:fuente
... Me pregunto cuántas soluciones complicadas se pueden crear al resolver este problema.
Puede ser tan fácil ...
ponga 1 línea siguiente al final del archivo como:
Si desea ejecutar algo cada 1 segundo, simplemente coloque allí:
y dentro de ese archivo.sh debería ser:
¡y eso es todo!
¡DISFRUTAR!
fuente
funciona para mi.
fuente