Bash OSX, polecenie „obserwuj”

292

Szukam najlepszego sposobu na zduplikowanie komendy Linux „obserwuj” w systemie Mac OSX. Chciałbym uruchamiać polecenie co kilka sekund, aby wzorować dopasowanie do zawartości pliku wyjściowego za pomocą „tail” i „sed”.

Jaka jest moja najlepsza opcja na komputerze Mac i czy można tego dokonać bez pobierania oprogramowania?

joseph.hainline
źródło
2
Dlaczego chcesz go zduplikować, skoro możesz go po prostu zainstalować?
Andrew Marshall,
3
ponieważ musiałbym skonfigurować wszystkie komputery Mac w biurze, które
używają
Sugerowałbym, aby twój skrypt instalował napar, a następnie oglądał.
AsTeR
Zegarek Brew wydaje się nie odbierać poleceń na mojej ścieżce ani aliasów.
sam boosalis
Alternatywnie do polecenia można również użyć aplikacji /Applications/Utilities/Console.app do monitorowania plików dziennika. Umożliwia filtrowanie za pomocą podstawowego wyszukiwania
JuanMa Cuevas

Odpowiedzi:

335

Możesz emulować podstawową funkcjonalność za pomocą pętli powłoki:

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

To zapętli się na zawsze, wyczyści ekran, uruchomi polecenie i zaczeka dwie sekundy - podstawowa watch your_commandimplementacja.

Możesz pójść o krok dalej i stworzyć watch.shskrypt, który będzie akceptował your_commandi sleep_durationjako parametry:

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

while :; 
  do 
  clear
  date
  $1
  sleep $2
done
Daniel Pittman
źródło
2
Uważam, że zegarek pokazuje tylko pierwszy ekran wyników. Jeśli chcesz zrobić coś podobnego, zmień your_commandnayour_command 2>&1|head -10
Mark Eirich
10
Działa to całkiem dobrze, ale wolę, sleep ${2:-1}aby interwał był opcjonalny.
Daniel Lubarov,
2
Ponadto jest to echo "$(date)"równoważne z date?
Daniel Lubarov
5
Nie działa również z rurami. Oto rozwidlenie z różnymi ulepszeniami: daniel.lubarov.com/simple-watch-script-for-osx
Daniel Lubarov
Nie działa tak, watchgdy wyjście jest więcej niż jednym ekranem. Pokazuje tylko koniec, a watchtylko górę. (Żadne z nich nie jest idealne)
h__
545

Z zainstalowanym Homebrew :

brew install watch

seantomburke
źródło
23
Zdecydowanie droga, jeśli używasz brewna komputerze Mac.
Maxence
2
Więcej szczegółów będzie mile widziane. Kiedy szukam „brew watch osx”, jest to najlepszy wynik wyszukiwania. EDYCJA: Najwyraźniej jest to polecenie Linuksa. Dla tych, którzy nie byli pewni, jak korzystać watch: stackoverflow.com/questions/13593771/...
gwg
2
watchWydaje się, że to z naparu nie odczytuje aliasów użytkownika. Podczas wykonywania watch somealiaspojawia się polecenie, którego nie znaleziono.
RNickMcCandless
@NickMc właściwym sposobem korzystania z zegarka jest watch [command]skorzystanie z watch somealiasniego, zakładając, że somealiasjest to polecenie, które można uruchomić w terminalu.
seantomburke
38

Użyj macports :

$ sudo port install watch
GoTLiuM
źródło
3
Nie ma lepszego sposobu niż watchbezpośrednie użycie polecenia.
Oliver,
8
Dlaczego warto stosować napar zamiast MacPorts?
bmauter
1
@bmauter, do każdego z nich: stackoverflow.com/questions/21374366/…
CenterOrbit
4
@CenterOrbit, właśnie dlatego zapytałem. @ joseph.hainline mówi, że nie używaj MacPorts, ale nie podaje dlaczego. Czy watchpolecenie zostało zablokowane w MacPorts?
bmauter,
To nie jest odpadło. To okropna rada. MacPorts działa świetnie i ma mnóstwo pakietów. Użyj tego.
Ali Gangji,
16

powyższe powłoki załatwi sprawę, możesz nawet przekonwertować je na alias (może być konieczne zawinięcie funkcji do obsługi parametrów)

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

Przykłady:

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

Alternatywnie, homebrew może zainstalować zegarek ze strony http://procps.sourceforge.net/

brew install watch
IT Gumby
źródło
14

Być może „oglądanie” nie jest tym, czego chcesz. Prawdopodobnie chcesz poprosić o pomoc w rozwiązaniu problemu, a nie we wdrożeniu rozwiązania! :)

Jeśli Twoim prawdziwym celem jest wyzwalanie akcji na podstawie tego, co widać z tailpolecenia , możesz to zrobić jako część samego ogona. Zamiast „okresowo” watchuruchamiać kod na żądanie .

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

Pamiętaj, że tail -Fnadal będzie śledzić plik dziennika, nawet jeśli zostanie on obrócony przez newsyslog lub logrotate. Chcesz użyć tego zamiast małych liter tail -f. Sprawdź man tailszczegóły.

To powiedziawszy, jeśli naprawdę chcesz okresowo uruchamiać komendę, inne podane odpowiedzi można przekształcić w krótki skrypt powłoki:

#!/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
źródło
Niestety ten skrypt powłoki nie działa z parametrami rozszerzonymi bash, takimi jak: watch 2 cat *
Code Commander
1
@CodeCommander - Linia poleceń watch 2 cat *rozszerza parametry przed uruchomieniem skryptu, więc w katalogu z plikami „foo” i „bar” uruchamiałbyś się cat foo barco 2 sekundy. Jakiego zachowania się spodziewałeś?
ghoti
@ghoti Po prostu wskazuję, że zachowanie różni się od polecenia watch na Ubuntu. Wersja Ubuntu najwyraźniej uruchamia polecenie co dwie sekundy (rozszerzając parametry przy każdym uruchomieniu), skrypt ten rozszerza parametry przed uruchomieniem, a następnie uruchamia się przy użyciu tych samych parametrów co dwie sekundy. Jeśli więc chcesz oglądać pliki w katalogu, w którym pliki są dodawane i usuwane, ten skrypt nie pomaga. Jest to przydatne, gdy nie używasz parametrów rozszerzonych. :)
Code Commander
@CodeCommander, myślę, że się mylisz. Bash (podobnie jak sh) rozwija się *bez przekazywania go do uruchomionego polecenia. Spróbuj uruchomić: mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*w jednym oknie. Gdy to działa, możesz touch /tmp/zz/barw innym oknie. Sprawdź, czy Twój „zegarek” widzi zmianę w pierwszym oknie. Nie sądzę, że tak będzie. To nie dla mnie. Nie ma to nic wspólnego z Ubuntu vs OSX lub Linux vs Unix, jest to zachowanie bashsamego siebie.
ghoti
1
@ghoti, masz rację. Myliłem się. Nawet z poleceniem watch w Linuksie musisz używać cudzysłowów, watch "ls -l /tmp/zz/*"ale jeśli pamiętasz o cudzysłowach, to również działa ze skryptem. :)
Code Commander
10

Idąc z odpowiedzią stąd :

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

Ale naprawdę lepiej jest zainstalować zegarek, ponieważ nie jest to zbyt czyste ...

Marvin Pinto
źródło
11
teraz nawet łatwiejbrew install watch
Peter Host
6

Jeśli zegarek nie chce instalować przez

brew install watch

Jest kolejna podobna / skopiowana wersja, która zainstalowała się i działała idealnie dla mnie

brew install visionmedia-watch

https://github.com/tj/watch

A_funs
źródło
5

Lub w twoim ~ / .bashrc

function watch {
    while :; do clear; date; echo; $@; sleep 2; done
}
jon
źródło
2

Miałem podobny problem.

Kiedy googlowałem, ostatnio natknąłem się na ten link. To nie jest dokładnie „instalacja oprogramowania”, po prostu pobranie pliku binarnego dla polecenia „obserwuj”.

Link to polecenie Pobierz zegarek dla OSX

sugavaneshb
źródło
1

Oto nieco zmieniona wersja tej odpowiedzi, która:

  • sprawdza poprawność argumentów
  • u góry wyświetla datę i czas trwania
  • przenosi argument „czas trwania” na pierwszy argument, dzięki czemu złożone polecenia można łatwo przekazać jako pozostałe argumenty.

Aby go użyć:

  • Zapisz to do ~/bin/watch
  • wykonać chmod 700 ~/bin/watchw terminalu, aby był wykonywalny.
  • spróbuj uruchomić 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
źródło
1

Spróbuj tego:

#!/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
źródło
1

aby zapobiec migotaniu, gdy wykonanie głównego polecenia zajmuje zauważalny czas, możesz uchwycić wyjście i wyczyścić ekran dopiero po jego zakończeniu.

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

następnie użyj go przez: watch istats

tungv
źródło
0

Użyj menedżera pakietów nix !

Zainstaluj nix, a następnie nix-env -iA nixpkgs.watchpowinien on być dostępny do użycia po wykonaniu instrukcji instalacji (w tym w źródle . "$HOME/.nix-profile/etc/profile.d/nix.sh"w powłoce).

galva
źródło