OSX bash, команда "watch"


292

Я шукаю найкращий спосіб дублювати команду Linux 'watch' на Mac OSX. Я хотів би запускати команду кожні кілька секунд, щоб відповідати шаблону вмісту вихідного файлу, використовуючи «хвіст» та «sed».

Який найкращий варіант на Mac, і чи можна це зробити без завантаження програмного забезпечення?


2
Чому б ви хотіли дублювати його, коли ви могли просто встановити його?
Ендрю Маршалл

3
тому що мені довелося б налаштувати всі Маки в офісі, щоб користувач мій сценарій
joseph.hainline

Я б запропонував, щоб ваш сценарій встановлював варити, а потім дивився.
AsTeR

Годинник Brew, схоже, не збирає команди на моєму шляху чи псевдонімах.
sam boosalis

В якості альтернативи команді ви також можете застосувати додаток /Applications/Utilities/Console.app для контролю файлів журналів. Він дозволяє фільтрувати за допомогою базового пошуку
JuanMa Cuevas,

Відповіді:


335

Ви можете імітувати основну функціональність за допомогою петлі оболонки:

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

Це назавжди замкнеться, очистить екран, запустить вашу команду та зачекає дві секунди - основна watch your_commandреалізація.

Ви можете зробити цей крок далі і створити watch.shсценарій, який може приймати your_commandі sleep_durationяк параметри:

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

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

2
Я вважаю, що годинник показує лише перший скріншот виходу. Якщо ви хочете зробити щось подібне, перейдіть your_commandнаyour_command 2>&1|head -10
Марк Ейріх

10
Це працює досить добре, але я вважаю sleep ${2:-1}за краще зробити інтервал необов’язковим.
Даніель Любаров

2
Також це echo "$(date)"еквівалентно date?
Даніель Любаров

5
Він також не працює з трубами. Ось вилка з різними вдосконаленнями: daniel.lubarov.com/simple-watch-script-for-osx
Даніель Любаров

Не працює так, watchколи вихід має більше одного екрана. Показує лише кінець, тоді watchяк показує лише верх. (Ні ідеально)
h__

546

З встановленим Homebrew :

brew install watch


23
Однозначно шлях, якщо ви користуєтеся brewна mac.
Максенція

2
Детальніше буде вдячно. Коли я шукаю "brew watch osx", це найкращий результат пошуку. EDIT: Мабуть, це команда Linux. Для тих , хто не був упевнений , як використовувати watch: stackoverflow.com/questions/13593771 / ...
GWG

2
Це, watchможливо, від Brew не читає псевдоніми користувачів. Під час виконання watch somealiasя отримую команду не знайдено.
RNickMcCandless

@NickMc - це правильний спосіб використання годинника, watch [command]коли ви користуєтесь watch somealiasним, якщо припустити, що somealiasце команда, яку можна запустити у своєму терміналі.
seantomburke

38

Використовуйте макспорт :

$ sudo port install watch

3
Немає кращого способу, ніж watchбезпосередньо використовувати команду.
Олівер

8
Навіщо використовувати варити замість MacPorts?
bmauter

1
@bmauter, кожному своє: stackoverflow.com/questions/21374366 / ...
CenterOrbit

4
@CenterOrbit, саме тому я запитав. @ joseph.hainline говорить, що не використовуйте MacPorts, але не вказує чому. Чи watchзаповнена команда в MacPorts?
bmauter

Це не розбито. Це жахлива порада. MacPorts чудово працює і має багато пакетів. Використай це.
Алі Ганджі

16

оболонки, наведені вище, зроблять трюк, ви навіть можете їх перетворити на псевдонім (можливо, потрібно буде перетворити функцію на обробку параметрів)

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

Приклади:

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

Як альтернатива, домашня мова може встановити годинник з http://procps.sourceforge.net/

brew install watch

14

Можливо, «дивитися» - це не те, чого ти хочеш. Напевно, ви хочете попросити допомоги у вирішенні своєї проблеми, а не в реалізації свого рішення! :)

Якщо ваша реальна мета - запустити дії, засновані на тому, що видно з tailкоманди , то ви можете це зробити як частину самого хвоста. Замість запуску "періодично", що і watchробить, ви можете запускати код на вимогу .

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

Зауважте, що tail -Fі надалі слідкуйте за файлом журналу, навіть якщо він повертається новинним журналом чи логротатом. Ви хочете використовувати це замість малих регістрів tail -f. Перевірте man tailдеталі.

Однак, якщо ви дійсно хочете періодично запускати команду, інші надані відповіді можна перетворити на короткий сценарій оболонки:

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

На жаль, цей скрипт оболонки не працює з розширеними параметрами bash, такими як: watch 2 cat *
Code Commander

1
@CodeCommander - Командний рядок watch 2 cat *розширить параметри перед запуском сценарію, тому в каталозі з файлами "foo" і "bar" ви запускаєте cat foo barкожні 2 секунди. Якої поведінки ви очікували?
ghoti

@ghoti Я просто вказую, що поведінка відрізняється від команди watch на Ubuntu. Версія Ubuntu, очевидно, виконує команду кожні дві секунди (розширюючи параметри кожного разу, коли вона запускається), цей сценарій розширює параметри до його запуску, а потім запускає з використанням одних і тих же параметрів кожні дві секунди. Тож якщо ви хочете переглянути файли в каталозі, де файли додаються та видаляються, цей скрипт не допоможе. Це корисно, коли ви не використовуєте розширені параметри. :)
Командир коду

@CodeCommander, я думаю, ти помилився. Bash (як sh) розширюється, *не передаючи його команді, яку ви виконуєте. Спробуйте запустити: mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*в одному вікні. Поки це працює, ви можете touch /tmp/zz/barв іншому вікні. У першому вікні дивіться, чи бачить ваш "годинник" зміни. Я не думаю, що це буде. Це не для мене. Це не має нічого спільного з Ubuntu vs OSX або Linux проти Unix, це поведінка bashсама по собі.
ghoti

1
@ghoti, ти маєш рацію. Я помилився. Навіть за допомогою команди Linux watch потрібно використовувати лапки: watch "ls -l /tmp/zz/*"але якщо ви пам’ятаєте використовувати цитати, вона працює і з вашим сценарієм. :)
Командир коду


6

Якщо годинник не хоче встановлювати через

brew install watch

Є ще одна схожа / копіювальна версія, яка встановила і працювала ідеально для мене

brew install visionmedia-watch

https://github.com/tj/watch


5

Або у вашому ~ / .bashrc

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

2

У мене була подібна проблема.

Коли я гуглився, нещодавно натрапив на це посилання. Це не зовсім "встановлення програмного забезпечення", а просто отримання двійкового для команди "watch".

І посилання - Get Get command для OSX


2

щоб запобігти мерехтінню, коли ваша головна команда потребує значного часу для завершення, ви можете зафіксувати вихід і лише очистити екран, коли це виконано.

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

потім використовуйте його: watch istats


Потрібно echo -eзамість того echo, щоб просто зробити ці розриви рядків правильно
jez

1

Ось дещо змінена версія цієї відповіді, що:

  • перевірки на дійсні аргументи
  • вгорі відображається назва дати та тривалості
  • переміщує аргумент "тривалість" на 1-й аргумент, тому складні команди можуть бути легко передані як інші аргументи.

Щоб використовувати його:

  • Збережіть це в ~/bin/watch
  • виконати chmod 700 ~/bin/watchв терміналі, щоб зробити його виконуваним.
  • спробуйте, запустивши watch 1 echo "hi there"

~ / бін / дивитися

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

Спробуйте це:

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

0

Використовуйте менеджер пакунків nix !

Встановіть nix, тоді nix-env -iA nixpkgs.watchвін повинен бути доступний для використання після завершення інструкцій із встановлення (включаючи пошук . "$HOME/.nix-profile/etc/profile.d/nix.sh"у вашій оболонці).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.