it-swarm-es.com

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

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

No hay necesidad de un script, solo necesito un comando simple para ejecutar en la terminal.

132
user239745

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

Abra la Terminal y escriba:

watch -n x <your command>

cambie x para que sea el tiempo en segundos que desee.

Para obtener más ayuda con el 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 de escritorio para que pueda saber si se produjeron cambios:

watch -n 60 ls -l ~/Desktop
213
nux

También puede usar este comando en la 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.

Utilizar Ctrl+C para detener el proceso.

Hay algunos inconvenientes de watch

  • No puede usar ningún comando con alias.
  • Si la salida de cualquier comando es bastante larga, el desplazamiento no funciona correctamente.
  • Hay algunos problemas para configurar intervalo de tiempo máximo más allá de cierto valor.
  • watch interpretará las secuencias de color ANSI que pasan 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.

86
souravc

Solo quería participar en las respuestas de souravc y nux:

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

Suena como la tarea ideal para el demonio 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 y relacionados con el tiempo seguidos de 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 Python todos los martes a las 11 AM:

0 11 * * 1 python ~/yourscript.py

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

# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"
11
Lekensteyn

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

Ejemplo:

En 1st terminal escriba este comando:

$ inotifywait .

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

$ touch newfile

Luego, en la terminal original, Inotifywait se despertará 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.
5
X Tian

puedes usar crontab. ejecuta el comando crontab -e y ábrelo con tu editor de texto preferido, luego agrega esta línea

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

Esto ejecutará tu 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
4
Maythux

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

Primero, abra su archivo .bash_aliases:

$ xdg-open ~/.bash-aliases

En segundo lugar, pegue estas líneas en la parte inferior del archivo y guarde:

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

Tercero, cierre y abra nuevamente su terminal o escriba:

$ source ~/.bash_aliases

Et voilà! Ahora puede usarlo así:

$ repeat 5 echo Hello World !!!

o

$ repeat 5 ./myscript.sh
4
Blufter

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 comienzas a ejecutar algo durante 4 minutos, que muestra lentamente varias páginas de contenido, realmente no lo verás.

Por otro lado, la preocupación con el enfoque "while" es que no toma en cuenta 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 puede tomar 1m40. Entonces, incluso si un cron podrá ejecutarlo cada minuto, aquí no lo hará.

Por lo tanto, para ver la salida en el Shell a medida que se genera y esperar el tiempo exacto de solicitud, debe mirar el tiempo antes y después, y recorrer el tiempo.

Algo 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 minuto:

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 se ejecutará, en el terminal/Shell, exactamente cada minuto. Si desea otro horario, simplemente cambie los "60" segundos con lo que necesite.

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
3
jmspaggi