OSX bash, comando 'watch'


292

Estou procurando a melhor maneira de duplicar o comando 'watch' do Linux no Mac OSX. Eu gostaria de executar um comando a cada poucos segundos para fazer a correspondência de padrões no conteúdo de um arquivo de saída usando 'tail' e 'sed'.

Qual é a minha melhor opção em um Mac e isso pode ser feito sem o download de software?


2
Por que você deseja duplicá-lo quando você pode apenas instalá-lo?
Andrew Marshall

3
porque eu teria que configurar todos os Macs no escritório que o usuário o meu script
joseph.hainline

Sugiro que o seu script instale o brew e depois assista.
áster

O relógio de cerveja parece não pegar comandos no meu caminho ou pseudônimos.
sam boosalis

Como alternativa a um comando, você também pode usar o aplicativo /Applications/Utilities/Console.app para monitorar arquivos de log. Permite filtrar com pesquisa básica
JuanMa Cuevas

Respostas:


335

Você pode emular a funcionalidade básica com o loop do shell:

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

Isso fará um loop para sempre, limpe a tela, execute seu comando e aguarde dois segundos - a watch your_commandimplementação básica .

Você pode dar um passo adiante e criar um watch.shscript que possa aceitar your_commande sleep_durationcomo parâmetros:

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

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

2
Eu acredito que o relógio mostra apenas a primeira tela cheia de saída. Se você quiser fazer algo semelhante, mude your_commandparayour_command 2>&1|head -10
Mark Eirich 10/11

10
Isso funciona muito bem, mas eu prefiro sleep ${2:-1}tornar o intervalo opcional.
Daniel Lubarov

2
Além disso, é echo "$(date)"equivalente a date?
Daniel Lubarov

5
Também não funciona com tubos. Aqui está um garfo com várias melhorias: daniel.lubarov.com/simple-watch-script-for-osx
Daniel Lubarov

Não funciona como watchquando a saída é mais de uma tela. Mostra apenas o final, enquanto watchmostra apenas o topo. (Nem é o ideal)
h__ 05/02

545

Com o Homebrew instalado:

brew install watch


23
Definitivamente o caminho a percorrer se você usar brewno mac.
Maxence

2
Mais detalhes seriam apreciados. Quando pesquiso "brew watch osx", este é o principal resultado da pesquisa. Edição: Aparentemente, é um comando do Linux. Para aqueles que não tinham certeza de como usar watch: stackoverflow.com/questions/13593771/…
gwg

2
Isso watchdo brew não parece ler os aliases do usuário. Ao executar watch somealias, recebo um comando não encontrado.
RNickMcCandless

O @NickMc, a maneira correta de usar o watch, é watch [command]quando você o usa watch somealias, assumindo que somealiasé um comando que você pode executar no seu terminal.
Seantomburke

38

Use macports :

$ sudo port install watch

3
Não há maneira melhor do que usar o watchcomando diretamente.
Oliver

8
Por que usar o brew em vez do MacPorts?
bmauter


4
@ CenterOrbit, é exatamente por isso que perguntei. @ joseph.hainline diz que não usa MacPorts, mas não indica o porquê. O watchcomando foi preso no MacPorts?
bmauter

Não está preso. Esse é um conselho terrível. MacPorts funciona muito bem e tem toneladas de pacotes. Use-o.
Ali Gangji

16

os shells acima farão o truque, você pode até convertê-los em um alias (talvez seja necessário agrupar uma função para manipular parâmetros)

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

Exemplos:

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

Como alternativa, a homebrew pode instalar o relógio em http://procps.sourceforge.net/

brew install watch

14

Pode ser que "assistir" não seja o que você deseja. Você provavelmente deseja pedir ajuda para resolver seu problema, não para implementar sua solução! :)

Se seu objetivo real é acionar ações com base no que é visto no tailcomando , você pode fazer isso como parte da própria cauda. Em vez de executar "periodicamente", que é o que watchfaz, você pode executar seu código sob demanda .

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

Observe que tail -Fcontinuará a seguir um arquivo de log, mesmo que ele seja rotacionado pelo newsyslog ou logrotate. Você deseja usar isso em vez de letras minúsculas tail -f. Verifique man tailpara detalhes.

Dito isto, se você realmente deseja executar um comando periodicamente, as outras respostas fornecidas podem ser transformadas em um pequeno script de shell:

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

Infelizmente, este script shell não funciona com parâmetros festança expandida, tais como: relógio 2 gato *
Código Commander

1
@CodeCommander - A linha de comando watch 2 cat *expandia os parâmetros antes de executar o script; portanto, em um diretório com os arquivos "foo" e "bar", você executaria a cat foo barcada 2 segundos. Que comportamento você esperava?
ghoti

@ ghoti Estou apenas apontando que o comportamento é diferente do comando watch no Ubuntu. Aparentemente, a versão do Ubuntu executa o comando a cada dois segundos (expandindo os parâmetros toda vez que é executado), esse script tem os parâmetros expandidos antes de ser executado e, em seguida, é executado usando os mesmos parâmetros a cada dois segundos. Portanto, se você deseja assistir aos arquivos em um diretório em que os arquivos estão sendo adicionados e removidos, esse script não ajuda. É útil quando você não usa parâmetros expandidos. :)
Comandante de código

@ CodeCommander, acho que você está enganado. O Bash (como sh) se expande *sem passar para o comando que você executa. Tente executar: mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*em uma janela. Enquanto estiver em execução, você pode touch /tmp/zz/barem outra janela. Veja se o seu "relógio" vê a alteração, na primeira janela. Eu acho que não. Não é para mim. Isso não tem nada a ver com Ubuntu vs OSX ou Linux vs Unix, é o comportamento em bashsi.
ghoti

1
@hothot, você está certo. Eu estava errado. Mesmo com o comando watch do Linux, você precisa usar aspas: watch "ls -l /tmp/zz/*"mas se você se lembrar de usar aspas, também funciona com o seu script. :)
Comandante de código


6

Se o relógio não quiser instalar via

brew install watch

Existe outra versão semelhante / cópia que foi instalada e funcionou perfeitamente para mim

brew install visionmedia-watch

https://github.com/tj/watch


5

Ou, no seu ~ / .bashrc

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

2

Eu tive um problema parecido.

Quando pesquisei no Google, me deparei com esse link recentemente. Isso não é exatamente 'instalação de software', simplesmente obter o binário para o comando 'watch'.

E o link é o comando Get watch para OSX


1

Aqui está uma versão ligeiramente alterada desta resposta que:

  • verifica se há argumentos válidos
  • mostra um título de data e duração no topo
  • move o argumento "duration" para ser o primeiro argumento, para que comandos complexos possam ser facilmente transmitidos como os argumentos restantes.

Para usá-lo:

  • Salve isso em ~/bin/watch
  • executar chmod 700 ~/bin/watchem um terminal para torná-lo executável.
  • tente executando 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

Tente o seguinte:

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

para evitar oscilações quando o comando principal leva um tempo perceptível para ser concluído, você pode capturar a saída e limpar a tela apenas quando terminar.

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

use-o por: watch istats


0

Use o gerenciador de pacotes nix !

Instale o nix e, em seguida, nix-env -iA nixpkgs.watchele estará disponível para uso após a conclusão das instruções de instalação (incluindo a fonte . "$HOME/.nix-profile/etc/profile.d/nix.sh"no shell).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.