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

292

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

Какой мой лучший вариант на Mac, и можно ли это сделать без загрузки программного обеспечения?

joseph.hainline
источник
2
Зачем вам дублировать его, если вы можете просто установить его?
Эндрю Маршалл
3
потому что я должен был бы настроить все компьютеры Mac в офисе, которые используют мой сценарий
joseph.hainline
Я бы предложил, чтобы ваш скрипт установил Brew, а затем посмотреть.
AsTeR
Часы brew, кажется, не собирают команды на моем пути или псевдонимах.
Сам 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
Mark Eirich
10
Это работает довольно хорошо, но я предпочитаю sleep ${2:-1}сделать интервал необязательным.
Даниэль Любаров
2
Кроме того, это echo "$(date)"эквивалентно date?
Даниэль Любаров
5
Это также не работает с трубами. Вот ответвление
Даниэль Любаров
Не работает, watchкогда на выходе более одного экрана. Показывает только конец, а watchпоказывает только верх. (Ни один из них не идеален)
h__
546

С Homebrew установлено:

brew install watch

seantomburke
источник
23
Определенно путь, если вы используете brewна Mac.
Maxence
2
Более подробная информация будет оценена. Когда я ищу "brew watch osx", это лучший результат поиска. РЕДАКТИРОВАТЬ: Очевидно, это команда Linux. Для тех, кто не был уверен, как использовать watch: stackoverflow.com/questions/13593771/…
gwg
2
Это watchот brew, кажется, не читает псевдонимы пользователя. При выполнении watch somealiasя получаю команду не найдена.
RNickMcCandless
@NickMc правильный способ использования watch - это watch [command]когда вы watch somealiasего используете, предполагая, что somealiasэто команда, которую вы можете запустить в своем терминале.
Seantomburke
38

Используйте macports :

$ sudo port install watch
GoTLiuM
источник
3
Нет лучшего способа, чем использовать watchкоманду напрямую.
Оливер
8
Зачем использовать brew вместо 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
IT Gumby
источник
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будет продолжать следовать за файлом журнала, даже если он будет повернут новостным журналом или logrotate. Вы хотите использовать это вместо строчных 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
Ghoti
источник
К сожалению, этот скрипт не работает с такими расширенными параметрами bash, как: watch 2 cat *
Code Commander
1
@CodeCommander - командная строка watch 2 cat *будет расширять параметры перед запуском скрипта, поэтому в каталоге с файлами «foo» и «bar» вы будете запускаться cat foo barкаждые 2 секунды. Какое поведение вы ожидали?
ghoti
@ghoti Я просто указываю, что поведение отличается от команды наблюдения в Ubuntu. Версия Ubuntu, по-видимому, запускает команду каждые две секунды (расширение параметров при каждом запуске), этот сценарий расширяет параметры перед запуском, а затем запускается с использованием тех же параметров каждые две секунды. Поэтому, если вы хотите просматривать файлы в каталоге, куда они добавляются и удаляются, этот скрипт не поможет. Это полезно, когда вы не используете расширенные параметры. :)
Code Commander
@CodeCommander, я думаю, ты ошибаешься. Bash (как sh) расширяется, *не передавая его команде, которую вы запускаете. Попробуйте запустить:mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/* в одном окне. Пока он работает, вы можете touch /tmp/zz/barв другом окне. Посмотрите, видят ли ваши «часы» изменения в первом окне. Я не думаю, что это будет. Это не для меня. Это не имеет ничего общего с Ubuntu против OSX или Linux против Unix, это поведение bashсамо по себе.
ghoti
1
@ ghoti, ты прав. Я ошибался. Даже с Linux-командой watch вам нужно использовать кавычки: watch "ls -l /tmp/zz/*"но если вы не забываете использовать кавычки, она работает и с вашим скриптом. :)
Code Commander
10

Собираюсь с ответом отсюда :

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

Но вам действительно лучше установить часы, так как они не очень чистые .

Марвин Пинто
источник
11
даже прощеbrew install watch
Питер Хозяин
6

Если часы не хотят устанавливать через

brew install watch

Есть другая аналогичная / копия версия, которая установлена ​​и отлично работает для меня

brew install visionmedia-watch

https://github.com/tj/watch

A_funs
источник
5

Или в вашем ~ / .bashrc

function watch {
    while :; do clear; date; echo; $@; sleep 2; done
}
джон
источник
2

У меня была похожая проблема.

Когда я гуглил, недавно наткнулся на эту ссылку. Это не совсем «установка программного обеспечения», просто получение двоичного кода для команды «смотреть».

И ссылка Get Get команда для OSX

sugavaneshb
источник
1

Вот слегка измененная версия этого ответа :

  • проверяет правильность аргументов
  • показывает дату и продолжительность заголовка вверху
  • перемещает аргумент «duration» в качестве первого аргумента, поэтому сложные команды могут быть легко переданы в качестве оставшихся аргументов.

Чтобы использовать это:

  • Сохранить это в ~/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
Роберт Нагтегал
источник
1

чтобы предотвратить мерцание, когда ваша основная команда занимает заметное время, вы можете захватить вывод и очистить экран только после того, как это будет сделано.

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

затем используйте его: watch istats

tungv
источник
0

Используйте менеджер пакетов nix !

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

Galva
источник