OSX-Bash, Befehl 'watch'


292

Ich suche nach dem besten Weg, um den Linux-Befehl 'watch' unter Mac OSX zu duplizieren. Ich möchte alle paar Sekunden einen Befehl ausführen, um die Musterübereinstimmung für den Inhalt einer Ausgabedatei mit 'tail' und 'sed' durchzuführen.

Was ist meine beste Option auf einem Mac und kann dies ohne Herunterladen von Software durchgeführt werden?


2
Warum sollten Sie es duplizieren, wenn Sie es einfach installieren könnten?
Andrew Marshall

3
weil ich alle Macs im Büro konfigurieren müsste, die mein Skript verwenden
joseph.hainline

Ich würde vorschlagen, dass Ihr Skript Brew installiert und dann anschaut.
AsTeR

Die Uhr von Brew scheint keine Befehle auf meinem Weg oder Aliase aufzunehmen.
Sam Boosalis

Alternativ zu einem Befehl können Sie auch die Anwendung /Applications/Utilities/Console.app verwenden, um Protokolldateien zu überwachen. Es ermöglicht das Filtern mit der einfachen Suche
JuanMa Cuevas

Antworten:


335

Sie können die Grundfunktionalität mit der Shell-Schleife emulieren:

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

Das wird für immer eine Schleife sein, den Bildschirm löschen, Ihren Befehl ausführen und zwei Sekunden warten - die grundlegende watch your_commandImplementierung.

Sie können noch einen Schritt weiter gehen und ein watch.shSkript erstellen , das your_commandund sleep_durationals Parameter akzeptiert :

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

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

2
Ich glaube, die Uhr zeigt nur den ersten Bildschirm der Ausgabe. Wenn Sie etwas Ähnliches tun möchten, wechseln Sie your_commandzuyour_command 2>&1|head -10
Mark Eirich

10
Das funktioniert ziemlich gut, aber ich ziehe sleep ${2:-1}es vor, das Intervall optional zu machen.
Daniel Lubarov

2
Auch ist es echo "$(date)"gleichbedeutend mit date?
Daniel Lubarov

5
Es funktioniert auch nicht mit Rohren. Hier ist eine Gabelung mit verschiedenen Verbesserungen: daniel.lubarov.com/simple-watch-script-for-osx
Daniel Lubarov

Funktioniert nicht wie watchbei mehr als einem Bildschirm. Zeigt nur das Ende an, während watchnur die Oberseite angezeigt wird. (
Beides

545

Mit installiertem Homebrew :

brew install watch


23
Auf jeden Fall der richtige Weg, wenn Sie brewauf einem Mac verwenden.
Maxence

2
Weitere Details wären willkommen. Wenn ich nach "Brew Watch Osx" suche, ist dies das Top-Suchergebnis. EDIT: Anscheinend ist es ein Linux-Befehl. Für diejenigen, die nicht sicher waren, wie man verwendet watch: stackoverflow.com/questions/13593771/…
gwg

2
Dies watchvon Brew scheint die Benutzer-Aliase nicht zu lesen. Bei der Ausführung watch somealiaswird ein Befehl nicht gefunden.
RNickMcCandless

@NickMc Die richtige Verwendung von watch ist, watch [command]wenn Sie es verwenden. Dies setzt voraus watch somealias, dass somealiases sich um einen Befehl handelt, den Sie in Ihrem Terminal ausführen können.
Seantomburke

38

Verwenden Sie Macports :

$ sudo port install watch

3
Es gibt keinen besseren Weg, als den watchBefehl direkt zu verwenden.
Oliver

8
Warum Brew anstelle von MacPorts verwenden?
Bmauter

1
@bmauter, zu jedem sein eigenes: stackoverflow.com/questions/21374366/…
CenterOrbit

4
@CenterOrbit, genau deshalb habe ich gefragt. @ joseph.hainline sagt, dass Sie keine MacPorts verwenden, gibt aber nicht an, warum. Wird der watchBefehl in MacPorts ausgeführt?
Bmauter

Es ist nicht kaputt. Das ist ein schrecklicher Rat. MacPorts funktioniert hervorragend und hat jede Menge Pakete. Benutze es.
Ali Gangji

16

Die obigen Shells reichen aus. Sie können sie sogar in einen Alias ​​konvertieren (möglicherweise müssen Sie eine Funktion einschließen, um Parameter zu verarbeiten).

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

Beispiele:

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

Alternativ kann Homebrew die Uhr von http://procps.sourceforge.net/ installieren.

brew install watch

14

Es kann sein, dass "beobachten" nicht das ist, was Sie wollen. Sie möchten wahrscheinlich um Hilfe bei der Lösung Ihres Problems bitten, nicht bei der Implementierung Ihrer Lösung! :) :)

Wenn Ihr eigentliches Ziel darin besteht, Aktionen basierend auf dem tailBefehl auszulösen , können Sie dies als Teil des Endes selbst tun. Anstatt "periodisch" ausgeführt zu werden, watchkönnen Sie Ihren Code bei Bedarf ausführen .

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

Beachten Sie, dass tail -Feine Protokolldatei auch dann weiter verfolgt wird, wenn sie von newsyslog oder logrotate gedreht wird. Sie möchten dies anstelle der Kleinbuchstaben verwenden tail -f. Überprüfen Sie man tailauf Details.

Wenn Sie jedoch wirklich regelmäßig einen Befehl ausführen möchten, können die anderen Antworten in ein kurzes Shell-Skript umgewandelt werden:

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

Leider funktioniert dieses Shell-Skript nicht mit erweiterten Bash-Parametern wie: watch 2 cat *
Code Commander

1
@CodeCommander - Die Befehlszeile watch 2 cat *erweitert die Parameter vor dem Ausführen des Skripts. In einem Verzeichnis mit den Dateien "foo" und "bar" werden Sie also cat foo baralle 2 Sekunden ausgeführt. Welches Verhalten haben Sie erwartet?
Ghoti

@ghoti Ich weise nur darauf hin, dass sich das Verhalten vom Befehl watch unter Ubuntu unterscheidet. Die Ubuntu-Version führt den Befehl anscheinend alle zwei Sekunden aus (erweitert die Parameter jedes Mal, wenn er ausgeführt wird). Bei diesem Skript werden die Parameter vor der Ausführung erweitert und dann alle zwei Sekunden mit denselben Parametern ausgeführt. Wenn Sie also Dateien in einem Verzeichnis anzeigen möchten, in dem Dateien hinzugefügt und entfernt werden, hilft dieses Skript nicht. Dies ist jedoch nützlich, wenn Sie keine erweiterten Parameter verwenden. :)
Code Commander

@ CodeCommander, ich denke du liegst falsch. Bash (wie sh) wird erweitert, *ohne es an den von Ihnen ausgeführten Befehl zu übergeben. Versuchen Sie es: mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*in einem Fenster. Während das läuft, können Sie touch /tmp/zz/barin einem anderen Fenster. Überprüfen Sie im ersten Fenster, ob Ihre "Uhr" die Änderung sieht. Ich glaube nicht. Es ist nicht für mich. Dies hat nichts mit Ubuntu vs OSX oder Linux vs Unix zu tun, es ist das Verhalten von bashsich.
Ghoti

1
@ghoti, du hast recht. Ich lag falsch. Selbst mit dem Linux-Befehl watch müssen Sie Anführungszeichen verwenden. watch "ls -l /tmp/zz/*"Wenn Sie jedoch daran denken, Anführungszeichen zu verwenden, funktioniert dies auch mit Ihrem Skript. :)
Code Commander


6

Wenn watch nicht über installieren möchte

brew install watch

Es gibt eine andere ähnliche / kopierte Version, die für mich perfekt installiert und funktioniert hat

brew install visionmedia-watch

https://github.com/tj/watch


5

Oder in Ihrem ~ / .bashrc

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

2

Ich hatte ein ähnliches Problem.

Als ich gegoogelt habe, bin ich kürzlich auf diesen Link gestoßen. Dies ist nicht gerade 'Software installieren', sondern nur die Binärdatei für den Befehl 'watch'.

Und der Link ist Get watch Befehl für OSX


1

Hier ist eine leicht geänderte Version dieser Antwort :

  • prüft auf gültige Argumente
  • Zeigt oben einen Titel für Datum und Dauer an
  • Verschiebt das Argument "Dauer" zum ersten Argument, sodass komplexe Befehle leicht als verbleibende Argumente übergeben werden können.

Um es zu benutzen:

  • Speichern Sie dies unter ~/bin/watch
  • chmod 700 ~/bin/watchin einem Terminal ausführen , um es ausführbar zu machen.
  • Probieren Sie es aus, indem Sie laufen 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

Versuche dies:

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

Um ein Flackern zu verhindern, wenn Ihr Hauptbefehl eine erkennbare Zeit in Anspruch nimmt, können Sie die Ausgabe erfassen und den Bildschirm erst dann löschen, wenn er fertig ist.

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

dann benutze es von: watch istats


0

Verwenden Sie den nix Paketmanager!

Installieren Sie dann nix nix-env -iA nixpkgs.watchund es sollte nach Abschluss der Installationsanweisungen (einschließlich Sourcing . "$HOME/.nix-profile/etc/profile.d/nix.sh"in Ihrer Shell) zur Verwendung verfügbar sein .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.