OSX bash, comando 'watch'


292

Sto cercando il modo migliore per duplicare il comando 'watch' di Linux su Mac OSX. Vorrei eseguire un comando ogni pochi secondi per trovare una corrispondenza del contenuto di un file di output usando 'tail' e 'sed'.

Qual è la mia migliore opzione su un Mac e può essere eseguita senza scaricare software?


2
Perché dovresti duplicarlo quando puoi semplicemente installarlo?
Andrew Marshall,

3
perché dovrei configurare tutti i Mac in ufficio che
useranno il

Vorrei suggerire che il tuo script installa brew e poi guarda.
AsTeR,

L'orologio brew non sembra raccogliere comandi sul mio percorso o alias.
Sam Boosalis,

In alternativa a un comando è anche possibile utilizzare l'applicazione /Applications/Utilities/Console.app per monitorare i file di registro. Consente il filtraggio con la ricerca di base
JuanMa Cuevas,

Risposte:


335

Puoi emulare le funzionalità di base con il loop shell:

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

Questo eseguirà un ciclo continuo, azzererà lo schermo, eseguirà il comando e attenderà due secondi: l' watch your_commandimplementazione di base .

Puoi fare un ulteriore passo avanti e creare uno watch.shscript che possa accettare your_commande sleep_durationcome parametri:

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

while :; 
  do 
  clear
  date
  $1
  sleep $2
done

2
Credo che l'orologio mostri solo il primo schermo dell'output. Se vuoi fare qualcosa di simile, cambia your_commandinyour_command 2>&1|head -10
Mark Eirich,

10
Funziona abbastanza bene, ma preferisco sleep ${2:-1}rendere l'intervallo facoltativo.
Daniel Lubarov,

2
Inoltre, echo "$(date)"equivale a date?
Daniel Lubarov,

5
Inoltre non funziona con i tubi. Ecco un fork con vari miglioramenti: daniel.lubarov.com/simple-watch-script-for-osx
Daniel Lubarov

Non funziona come watchquando l'output è più di una schermata. Mostra solo la fine, mentre watchmostra solo la parte superiore. (Nessuno dei due è l'ideale)
h__

545

Con Homebrew installato:

brew install watch


23
Sicuramente la strada da percorrere se si utilizza brewsu Mac.
Maxence,

2
Maggiori dettagli sarebbero apprezzati. Quando cerco "brew watch osx", questo è il risultato di ricerca principale. EDIT: Apparentemente è un comando Linux. Per coloro che non erano sicuri di come usare watch: stackoverflow.com/questions/13593771/...
GWG

2
Questo watchda brew non sembra leggere gli alias dell'utente. Durante l'esecuzione watch somealias, ottengo un comando non trovato.
RNickMcCandless

@NickMc il modo corretto di usare watch è fare watch [command]quando lo usi watch somealias, presupponendo che somealiassia un comando che puoi eseguire nel tuo terminale.
seantomburke,

38

Usa macports :

$ sudo port install watch

3
Non c'è modo migliore quindi usare watchdirettamente il comando.
Oliver,

8
Perché usare brew invece di MacPorts?
bmauter,


4
@CenterOrbit, questo è esattamente il motivo per cui ho chiesto. @Joseph.hainline dice di non usare MacPorts, ma non indica il perché. Il watchcomando è stato eliminato in MacPorts?
bmauter,

Non è rotto. È un consiglio terribile. MacPorts funziona alla grande e ha tonnellate di pacchetti. Usalo
Ali Gangji,

16

le shell sopra faranno il trucco, potresti persino convertirle in un alias (potrebbe essere necessario avvolgere una funzione per gestire i parametri)

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

Esempi:

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

In alternativa, homebrew può installare l'orologio da http://procps.sourceforge.net/

brew install watch

14

Può darsi che "guardare" non sia quello che vuoi. Probabilmente vuoi chiedere aiuto per risolvere il tuo problema, non per implementare la tua soluzione! :)

Se il tuo vero obiettivo è innescare azioni basate su ciò che viene visto dal tailcomando , allora puoi farlo come parte della coda stessa. Invece di eseguire "periodicamente", che è ciò che watchfa, è possibile eseguire il codice su richiesta .

#!/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

Si noti che tail -Fcontinuerà a seguire un file di registro anche se viene ruotato da newsyslog o logrotate. Si desidera utilizzare questo anziché il minuscolo tail -f. Controlla i man taildettagli.

Detto questo, se vuoi davvero eseguire periodicamente un comando, le altre risposte fornite possono essere trasformate in uno script di shell corta:

#!/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

Sfortunatamente questo script di shell non funziona con parametri espansi bash come: watch 2 cat *
Code Commander

1
@CodeCommander - La riga di comando watch 2 cat *espandeva i parametri prima di eseguire lo script, quindi in una directory con i file "pippo" e "barra", si eseguiva cat foo barogni 2 secondi. Che comportamento ti aspettavi?
ghoti,

@ghoti Sto solo sottolineando che il comportamento è diverso dal comando watch su Ubuntu. Apparentemente la versione di Ubuntu esegue il comando ogni due secondi (espandendo i parametri ogni volta che viene eseguito), questo script ha i parametri espansi prima di essere eseguito, quindi viene eseguito usando gli stessi parametri ogni due secondi. Quindi, se vuoi guardare i file in una directory in cui i file vengono aggiunti e rimossi, questo script non aiuta. È utile quando non si utilizzano parametri espansi. :)
Codice comandante

@CodeCommander, penso che ti sbagli. Bash (come sh) si espande *senza passare al comando eseguito. Prova a correre: mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*in una finestra. Mentre è in esecuzione, è possibile touch /tmp/zz/barin un'altra finestra. Vedi se il tuo "orologio" vede il cambiamento, nella prima finestra. Non penso che lo farà. Non per me Questo non ha nulla a che fare con Ubuntu vs OSX o Linux vs Unix, è il comportamento di bashse stesso.
ghoti,

1
@ghoti, hai ragione. Mi sono sbagliato. Anche con il comando watch di Linux devi usare le virgolette: watch "ls -l /tmp/zz/*"ma se ricordi di usare le virgolette funziona anche con il tuo script. :)
Codice comandante


6

Se l'orologio non desidera installare tramite

brew install watch

C'è un'altra versione simile / copia che ha installato e ha funzionato perfettamente per me

brew install visionmedia-watch

https://github.com/tj/watch


5

Oppure, nel tuo ~ / .bashrc

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

2

Ho avuto un problema simile.

Quando ho cercato su Google, mi sono imbattuto in questo link di recente. Non si tratta esattamente di "installare software", ma semplicemente di ottenere il binario per il comando "watch".

E il link è Ottieni il comando watch per OSX


1

Ecco una versione leggermente modificata di questa risposta che:

  • verifica la presenza di argomenti validi
  • mostra un titolo per data e durata in alto
  • sposta l'argomento "duration" come primo argomento, in modo che comandi complessi possano essere passati facilmente come gli argomenti rimanenti.

Per usarlo:

  • Salva questo in ~/bin/watch
  • eseguire chmod 700 ~/bin/watchin un terminale per renderlo eseguibile.
  • provalo correndo 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

1

Prova questo:

#!/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

1

per evitare lo sfarfallio quando il comando principale impiega un tempo percettibile per il completamento, è possibile catturare l'output e cancellare lo schermo solo al termine.

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

quindi usalo con: watch istats


0

Usa il gestore pacchetti nix !

Installa nix, quindi, nix-env -iA nixpkgs.watche dovrebbe essere disponibile per l'uso dopo aver completato le istruzioni di installazione (incluso il sourcing . "$HOME/.nix-profile/etc/profile.d/nix.sh"nella shell).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.