OSX bash, comando 'watch'

292

Estoy buscando la mejor manera de duplicar el comando 'watch' de Linux en Mac OSX. Me gustaría ejecutar un comando cada pocos segundos para que coincida el patrón en el contenido de un archivo de salida usando 'tail' y 'sed'.

¿Cuál es mi mejor opción en una Mac, y se puede hacer sin descargar software?

joseph.hainline
fuente
2
¿Por qué querrías duplicarlo si solo pudieras instalarlo?
Andrew Marshall
3
porque tendría que configurar todos los Mac en la oficina que
usan
Sugeriría que su script instale brew y luego mire.
AsTeR
Brew's Watch no parece captar comandos en mi camino o alias.
Sam Boosalis
Alternativamente a un comando, también puede usar la aplicación /Aplicaciones/Utilidades/Console.app para monitorear los archivos de registro. Permite el filtrado con búsqueda básica
JuanMa Cuevas

Respuestas:

335

Puede emular la funcionalidad básica con el bucle de shell:

while :; do clear; your_command; sleep 2; done

Eso se repetirá para siempre, borrará la pantalla, ejecutará su comando y esperará dos segundos: la watch your_commandimplementación básica .

Puede llevar esto un paso más allá y crear un watch.shscript que pueda aceptar your_commandy sleep_durationcomo parámetros:

#!/bin/bash
# usage: watch.sh <your_command> <sleep_duration>

while :; 
  do 
  clear
  date
  $1
  sleep $2
done
Daniel Pittman
fuente
2
Creo que watch solo muestra la primera pantalla llena de resultados. Si quieres hacer algo similar, cambia your_commandayour_command 2>&1|head -10
Mark Eirich
10
Esto funciona bastante bien, pero prefiero sleep ${2:-1}que el intervalo sea opcional.
Daniel Lubarov el
2
Además, es echo "$(date)"equivalente a date?
Daniel Lubarov
55
Tampoco funciona con tuberías. Aquí hay un tenedor con varias mejoras: daniel.lubarov.com/simple-watch-script-for-osx
Daniel Lubarov
No funciona como watchcuando la salida es más de una pantalla. Solo muestra el final, mientras que watchsolo muestra la parte superior. (Ninguno de los dos es ideal)
h__
545

Con Homebrew instalado:

brew install watch

Seantomburke
fuente
23
Definitivamente el camino a seguir si lo usa brewen Mac.
Maxence
2
Se agradecerían más detalles. Cuando busco "brew watch osx", este es el mejor resultado de búsqueda. EDITAR: Aparentemente es un comando de Linux. Para aquellos que no estaban seguros de cómo usar watch: stackoverflow.com/questions/13593771/…
gwg
2
Esto watchde brew no parece leer los alias de usuario. Al ejecutar watch somealias, recibo un comando no encontrado.
RNickMcCandless
@NickMc la forma correcta de usar watch es hacerlo watch [command]cuando lo usas watch somealias, suponiendo que somealiases un comando que puedes ejecutar en tu terminal.
seantomburke
38

Utiliza macports :

$ sudo port install watch
GoTLiuM
fuente
3
No hay mejor manera que usar el watchcomando directamente.
Oliver
8
¿Por qué usar brew en lugar de MacPorts?
bmauter
1
@bmauter, a cada uno lo suyo: stackoverflow.com/questions/21374366/…
CenterOrbit
44
@CenterOrbit, precisamente por eso pregunté. @ joseph.hainline dice que no use MacPorts, pero no explica por qué. ¿El watchcomando está roto en MacPorts?
bmauter
No está reventado. Ese es un consejo terrible. MacPorts funciona muy bien y tiene toneladas de paquetes. Úsalo.
Ali Gangji
16

los shells anteriores harán el truco, incluso podría convertirlos en un alias (puede que necesite envolver en una función para manejar parámetros)

alias myWatch='_() { while :; do clear; $2; sleep $1; done }; _'

Ejemplos:

myWatch 1 ls ## self-explanatory
myWatch 5 "ls -lF $HOME" ## every 5 seconds, list out home dir; double-quotes around command to keep its args together

Alternativamente, homebrew puede instalar el reloj desde http://procps.sourceforge.net/

brew install watch
IT Gumby
fuente
14

Puede ser que "mirar" no sea lo que quieres. ¡Probablemente quiera pedir ayuda para resolver su problema, no para implementar su solución! :)

Si su objetivo real es desencadenar acciones basadas en lo que se ve desde el tailcomando , puede hacerlo como parte de la cola misma. En lugar de ejecutar "periódicamente", que es lo que watchhace, puede ejecutar su código a pedido .

#!/bin/sh

tail -F /var/log/somelogfile | while read line; do
  if echo "$line" | grep -q '[Ss]ome.regex'; then
    # do your stuff
  fi
done

Tenga en cuenta que tail -Fseguirá un archivo de registro incluso si se rota por newsyslog o logrotate. Desea usar esto en lugar de las minúsculas tail -f. Consultar man tailpara más detalles.

Dicho esto, si realmente desea ejecutar un comando periódicamente, las otras respuestas proporcionadas se pueden convertir en un breve script de shell:

#!/bin/sh
if [ -z "$2" ]; then
  echo "Usage: $0 SECONDS COMMAND" >&2
  exit 1
fi

SECONDS=$1
shift 1
while sleep $SECONDS; do
  clear
  $*
done
ghoti
fuente
Desafortunadamente, este script de shell no funciona con parámetros expandidos de bash como: watch 2 cat *
Code Commander
1
@CodeCommander: la línea de comando watch 2 cat *expandiría los parámetros antes de ejecutar el script, por lo que en un directorio con los archivos "foo" y "bar", se ejecutaría cat foo barcada 2 segundos. ¿Qué comportamiento estabas esperando?
ghoti
@ghoti Simplemente estoy señalando que el comportamiento es diferente del comando watch en Ubuntu. La versión de Ubuntu aparentemente ejecuta el comando cada dos segundos (expandiendo los parámetros cada vez que se ejecuta), este script tiene los parámetros expandidos antes de ejecutarse, y luego se ejecuta utilizando los mismos parámetros cada dos segundos. Entonces, si desea ver archivos en un directorio donde se agregan y eliminan archivos, este script no ayuda. Sin embargo, es útil cuando no utiliza parámetros expandidos. :)
Code Commander
@CodeCommander, creo que estás equivocado. Bash (como sh) se expande *sin pasarlo al comando que ejecuta. Intenta correr: mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*en una ventana. Mientras se está ejecutando, puedes hacerlo touch /tmp/zz/baren otra ventana. Vea si su "reloj" ve el cambio, en la primera ventana. No creo que lo haga. No es para mi. Esto no tiene nada que ver con Ubuntu vs OSX o Linux vs Unix, es el comportamiento en bashsí mismo.
ghoti
1
@ghoti, tienes razón. Estaba equivocado. Incluso con el comando watch de Linux necesita usar comillas: watch "ls -l /tmp/zz/*"pero si recuerda usar comillas, también funciona con su script. :)
Code Commander
10

Yendo con la respuesta desde aquí :

bash -c 'while [ 0 ]; do <your command>; sleep 5; done'

Pero es mejor que instales el reloj ya que esto no es muy limpio .

Marvin Pinto
fuente
11
más fácil ahora inclusobrew install watch
Peter Host
6

Si watch no quiere instalar a través de

brew install watch

Hay otra versión similar / copia que se instaló y funcionó perfectamente para mí.

brew install visionmedia-watch

https://github.com/tj/watch

A_funs
fuente
5

O, en tu ~ / .bashrc

function watch {
    while :; do clear; date; echo; $@; sleep 2; done
}
jon
fuente
2

Tuve un problema similar.

Cuando busqué en Google, me encontré con este enlace recientemente. Esto no es exactamente 'instalar software', simplemente obtener el binario para el comando 'watch'.

Y el enlace es el comando Obtener reloj para OSX

sugavaneshb
fuente
1

Aquí hay una versión ligeramente modificada de esta respuesta que:

  • comprueba si hay argumentos válidos
  • muestra un título de fecha y duración en la parte superior
  • mueve el argumento de "duración" para ser el primer argumento, por lo que los comandos complejos se pueden pasar fácilmente como los argumentos restantes.

Para usarlo:

  • Guarda esto en ~/bin/watch
  • ejecutar chmod 700 ~/bin/watchen una terminal para hacerlo ejecutable.
  • pruébalo corriendo watch 1 echo "hi there"

~ / bin / watch

#!/bin/bash

function show_help()
{
  echo ""
  echo "usage: watch [sleep duration in seconds] [command]"
  echo ""
  echo "e.g. To cat a file every second, run the following"
  echo ""
  echo "     watch 1 cat /tmp/it.txt" 
  exit;
}

function show_help_if_required()
{
  if [ "$1" == "help" ]
  then
      show_help
  fi
  if [ -z "$1" ]
    then
      show_help
  fi
}

function require_numeric_value()
{
  REG_EX='^[0-9]+$'
  if ! [[ $1 =~ $REG_EX ]] ; then
    show_help
  fi
}

show_help_if_required $1
require_numeric_value $1

DURATION=$1
shift

while :; do 
  clear
  echo "Updating every $DURATION seconds. Last updated $(date)"
  bash -c "$*"
  sleep $DURATION
done
Brad Parks
fuente
1

Prueba esto:

#!/bin/bash
# usage: watch [-n integer] COMMAND

case $# in
    0)
        echo "Usage $0 [-n int] COMMAND"
        ;;
    *)      
        sleep=2;
        ;;
esac    

if [ "$1" == "-n" ]; then
    sleep=$2
    shift; shift
fi


while :; 
    do 
    clear; 
    echo "$(date) every ${sleep}s $@"; echo 
    $@; 
    sleep $sleep; 
done
Robert Nagtegaal
fuente
1

Para evitar el parpadeo cuando su comando principal tarda un tiempo perceptible en completarse, puede capturar la salida y solo borrar la pantalla cuando esté listo.

function watch {while :; do a=$($@); clear; echo "$(date)\n\n$a"; sleep 1; done}

luego úsalo por: watch istats

tungv
fuente
0

¡Usa el administrador de paquetes nix !

Instale nix, entonces, nix-env -iA nixpkgs.watchy debería estar disponible para su uso después de completar las instrucciones de instalación (incluido el abastecimiento . "$HOME/.nix-profile/etc/profile.d/nix.sh"en su shell).

galva
fuente