¿Repite un comando cada x intervalo de tiempo en la terminal?

123

¿Cómo puedo repetir un comando cada intervalo de tiempo, de modo que me permita ejecutar comandos para consultar o supervisión de directorios?

No hay necesidad de un script, solo necesito un comando simple para ser ejecutado en el terminal.

    
pregunta muru 06.03.2014 - 16:52

8 respuestas

188

Puedes usar el comando watch , mirar se usa para ejecutar cualquier comando designado a intervalos regulares.

Abrir terminal y escribir:

watch -n x <your command>

cambia x para que sea el tiempo en segundos que quieras.

Para obtener más ayuda sobre el uso del comando watch y sus opciones, ejecute man watch o visite este Enlace .

Por ejemplo: la siguiente lista, cada 60s , en el mismo Terminal, el contenido del directorio del Escritorio para que pueda saber si se produjeron cambios:

watch -n 60 ls -l ~/Desktop
    
respondido por el nux 06.03.2014 - 16:54
75

También puedes usar este comando en terminal, aparte de la respuesta de nux:

while true; do <your_command>; sleep <interval_in_seconds>; done

Ejemplo

while true; do ls; sleep 2; done

Este comando imprimirá la salida de ls en un intervalo de 2 segundos.

Utilice Ctrl + C para detener el proceso.

Hay algunos inconvenientes de watch

  • No puede usar ningún comando con alias.
  • Si el resultado de cualquier comando es bastante largo, el desplazamiento no funciona correctamente.
  • Hay algunos problemas para establecer intervalo de tiempo máximo más allá de cierto valor.
  • watch interpretará las secuencias de color ANSI que pasan los caracteres de escape utilizando la opción -c o --color . Por ejemplo, la salida de pygmentize funcionará pero fallará para ls --color=auto .

En las circunstancias anteriores, esto puede aparecer como una mejor opción.

    
respondido por el souravc 06.03.2014 - 17:00
31

Solo quería colaborar con las respuestas de souravc y nux :

  1. Si bien watch funcionará perfectamente en Ubuntu, es posible que desee evitar eso si quiere que su "Unix-fu" sea puro; en FreeBSD, por ejemplo, watch es un comando para "fisgonear en otra línea tty".
  2. while true; do command; sleep SECONDS; done también tiene una advertencia: es posible que tu comando sea más difícil de eliminar con CTR + C . Es posible que desee preferir while sleep SECONDS; do command; done ; no solo es más corto, sino también más fácil de interrumpir. La advertencia es que primero dormirá, luego ejecutará su comando, por lo que tendrá que esperar un SECONDS antes de que ocurra la primera aparición del comando.
respondido por el d33tah 08.03.2014 - 16:51
11

Suena como la tarea ideal para el daemon cron que permite ejecutar comandos periódicos. Ejecute el comando crontab -e para comenzar a editar la configuración cron de su usuario. Su formato está documentado en crontab (5) . Básicamente, tiene cinco campos separados por espacios separados por espacios seguidos por un comando:

The time and date fields are:

       field          allowed values
       -----          --------------
       minute         0-59
       hour           0-23
       day of month   1-31
       month          1-12 (or names, see below)
       day of week    0-7 (0 or 7 is Sunday, or use names)

Por ejemplo, si desea ejecutar un script de Python cada martes, a las 11:00 a.m.:

0 11 * * 1 python ~/yourscript.py

También hay algunos nombres especiales que reemplazan el tiempo, como @reboot . Muy útil si necesita crear un directorio temporal. De mi crontab (listado con crontab -l ):

# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"
    
respondido por el Lekensteyn 07.03.2014 - 19:54
4

Si está monitoreando el sistema de archivos, entonces inotifywait es brillante y ciertamente agrega menos carga en su sistema.

Ejemplo:

En la primera terminal escriba este comando:

$ inotifywait .

Luego, en el terminal 2nd , cualquier comando que afecte al directorio actual,

$ touch newfile

Luego, en la terminal original inotifywait se activará e informará el evento

./ CREATE newfile2

O en un bucle

$ while true ; do inotifywait . ; done
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ DELETE newfile
Setting up watches.  
Watches established.
./ CREATE,ISDIR newdir
Setting up watches.  
Watches established.
    
respondido por el X Tian 06.03.2014 - 17:35
4

Puede crear su propio comando repeat siguiendo los siguientes pasos; créditos aquí :

Primero, abra su archivo .bash_aliases :

$ xdg-open ~/.bash-aliases

Segundo, pegue estas líneas en la parte inferior del archivo y guárdelo:

repeat() {
n=
shift
while [ $(( n -= 1 )) -ge 0 ]
do
    "$@"
done
}

En tercer lugar, cierra y vuelve a abrir tu terminal o escribe:

$ source ~/.bash_aliases

Et voilà! Ahora puede usarlo así:

$ repeat 5 echo Hello World !!!

o

$ repeat 5 ./myscript.sh
    
respondido por el Blufter 08.08.2014 - 21:38
4

puedes usar crontab. ejecute el comando crontab -e y ábralo con su editor de texto preferido, luego agregue esta línea

*/10 * * * *  /path-to-your-command

Esto ejecutará su comando cada 10 minutos

* */4 * * *  /path-to-your-command

Esto ejecutará su comando cada 4 horas

Otra posible solución

$ ..some command...; for i in $(seq X); do $cmd; sleep Y; done

X número de veces para repetir.

Y tiempo de espera para repetir.

Ejemplo:

$ echo; for i in $(seq 5); do $cmd "This is echo number: $i"; sleep 1;done
    
respondido por el Maythux 07.03.2014 - 06:57
1

Otra preocupación con el enfoque de "observación" propuesto anteriormente es que muestra el resultado solo cuando se realiza el proceso. "date; sleep 58; date" mostrará las 2 fechas solo después de 59 segundos ... Si comienza algo que se ejecuta durante 4 minutos, que muestra lentamente varias páginas de contenido, no lo verá realmente.

Por otro lado, la preocupación con el enfoque "while" es que no toma en consideración la duración de la tarea.

while true; do script_that_take_between_10s_to_50s.sh; sleep 50; done

Con esto, el script se ejecutará en algún momento cada minuto, en algún momento podría tomar 1m40. Entonces, aunque un cron pueda ejecutarlo cada minuto, aquí no.

Entonces, para ver el resultado en el shell a medida que se genera y esperar el tiempo exacto de solicitud, debe mirar el tiempo anterior y posterior, y repetir con el tiempo.

Algo así como:

while ( true ); do
  echo Date starting 'date'
  before='date +%s'
  sleep 'echo $(( ( RANDOM % 30 )  + 1 ))'
  echo Before waiting 'date'
  after='date +%s'
  DELAY='echo "60-($after-$before)" | bc'
  sleep $DELAY
  echo Done waiting 'date'
done

Esto generará esto:

Como puede ver, el comando se ejecuta cada minutos:

Date starting Mon Dec 14 15:49:34 EST 2015
Before waiting Mon Dec 14 15:49:52 EST 2015
Done waiting Mon Dec 14 15:50:34 EST 2015

Date starting Mon Dec 14 15:50:34 EST 2015
Before waiting Mon Dec 14 15:50:39 EST 2015
Done waiting Mon Dec 14 15:51:34 EST 2015

Así que simplemente reemplace el comando "sleep echo $(( ( RANDOM % 30 ) + 1 )) " con lo que quiera y que se ejecutará, en el terminal / shell, exactamente cada minuto. Si quieres otro horario, simplemente cambia los "60" segundos con lo que necesites.

Versión más corta sin las líneas de depuración:

while ( true ); do
  before='date +%s'
  sleep 'echo $(( ( RANDOM % 30 )  + 1 ))' # Place you command here
  after='date +%s'
  DELAY='echo "60-($after-$before)" | bc'
  sleep $DELAY
done
    
respondido por el jmspaggi 14.12.2015 - 21:56

Lea otras preguntas en las etiquetas