OSX bash, commande 'watch'


292

Je cherche le meilleur moyen de dupliquer la commande Linux 'watch' sur Mac OSX. Je voudrais exécuter une commande toutes les quelques secondes pour faire correspondre les motifs au contenu d'un fichier de sortie en utilisant «tail» et «sed».

Quelle est ma meilleure option sur un Mac et peut-elle être effectuée sans télécharger de logiciel?


2
Pourquoi voudriez-vous le dupliquer alors que vous pouvez simplement l'installer?
Andrew Marshall

3
parce que je devrais configurer tous les Mac au bureau qui utilisent mon script
joseph.hainline

Je suggère que votre script installe brew puis regarde.
AsTeR

la montre de brassage ne semble pas capter les commandes sur mon chemin ou les alias.
sam boosalis

Alternativement à une commande, vous pouvez également utiliser l'application /Applications/Utilities/Console.app pour surveiller les fichiers journaux. Il permet le filtrage avec la recherche de base
JuanMa Cuevas

Réponses:


335

Vous pouvez émuler la fonctionnalité de base avec la boucle shell:

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

Cela bouclera pour toujours, effacera l'écran, exécutera votre commande et attendra deux secondes - l' watch your_commandimplémentation de base .

Vous pouvez aller plus loin et créer un watch.shscript pouvant accepter your_commandet sleep_durationcomme paramètres:

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

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

2
Je crois que la montre ne montre que le premier écran de sortie. Si vous voulez faire quelque chose de similaire, your_commandyour_command 2>&1|head -10
passez

10
Cela fonctionne plutôt bien, mais je préfère sleep ${2:-1}rendre l'intervalle facultatif.
Daniel Lubarov

2
De plus, c'est echo "$(date)"équivalent à date?
Daniel Lubarov

5
Cela ne fonctionne pas non plus avec les tuyaux. Voici une fourchette avec diverses améliorations: daniel.lubarov.com/simple-watch-script-for-osx
Daniel Lubarov

Ne fonctionne pas comme watchlorsque la sortie est composée de plusieurs écrans. Ne montre que la fin, alors que watchne montre que le haut. (Ni l'un ni l'autre n'est idéal)
h__

545

Avec Homebrew installé:

brew install watch


23
Certainement la voie à suivre si vous utilisez brewsur Mac.
Maxence

2
Plus de détails seraient appréciés. Lorsque je recherche «brew watch osx», c'est le meilleur résultat de recherche. EDIT: Apparemment, c'est une commande Linux. Pour ceux qui ne savaient pas comment utiliser watch: stackoverflow.com/questions/13593771/…
gwg

2
Cela watchde brew ne semble pas lire les alias des utilisateurs. Lors de l'exécution watch somealias, j'obtiens une commande introuvable.
RNickMcCandless

@NickMc la bonne façon d'utiliser watch est de le faire watch [command]lorsque vous l'utilisez watch somealiasen supposant que somealiasc'est une commande que vous pouvez exécuter dans votre terminal.
seantomburke

38

Utilisez macports :

$ sudo port install watch

3
Il n'y a pas de meilleur moyen que d'utiliser watchdirectement la commande.
Oliver

8
Pourquoi utiliser brew au lieu de MacPorts?
bmauter

1
@bmauter, à chacun son propre: stackoverflow.com/questions/21374366/…
CenterOrbit

4
@CenterOrbit, c'est précisément pourquoi j'ai demandé. @ joseph.hainline dit de ne pas utiliser MacPorts, mais ne précise pas pourquoi. La watchcommande est-elle supprimée dans MacPorts?
bmauter

Ce n'est pas éclaté. C'est un conseil terrible. MacPorts fonctionne très bien et propose des tonnes de packages. Utilise le.
Ali Gangji

16

les shells ci-dessus feront l'affaire, vous pouvez même les convertir en alias (vous devrez peut-être envelopper une fonction pour gérer les paramètres)

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

Exemples:

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

Alternativement, homebrew peut installer la montre depuis http://procps.sourceforge.net/

brew install watch

14

Il se peut que "regarder" ne soit pas ce que vous voulez. Vous voudrez probablement demander de l'aide pour résoudre votre problème, pas pour implémenter votre solution! :)

Si votre véritable objectif est de déclencher des actions en fonction de ce qui est vu à partir de la tailcommande , vous pouvez le faire dans le cadre de la queue elle-même. Au lieu d'exécuter "périodiquement", ce qui est le watchcas, vous pouvez exécuter votre code à la demande .

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

Notez que tail -Fcontinuera à suivre un fichier journal même s'il est tourné par newsyslog ou logrotate. Vous souhaitez utiliser ceci au lieu des minuscules tail -f. Vérifiez les man taildétails.

Cela dit, si vous voulez vraiment exécuter une commande périodiquement, les autres réponses fournies peuvent être transformées en un script shell court:

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

Malheureusement, ce script shell ne fonctionne pas avec les paramètres étendus bash tels que: watch 2 cat *
Code Commander

1
@CodeCommander - La ligne de commande watch 2 cat *développerait les paramètres avant d'exécuter le script, donc dans un répertoire avec les fichiers "foo" et "bar", vous vous exécuteriez cat foo bartoutes les 2 secondes. À quel comportement vous attendiez-vous?
ghoti

@ghoti Je souligne simplement que le comportement est différent de la commande watch sur Ubuntu. La version Ubuntu exécute apparemment la commande toutes les deux secondes (en développant les paramètres à chaque exécution), ce script a les paramètres développés avant son exécution, puis s'exécute en utilisant les mêmes paramètres toutes les deux secondes. Donc, si vous voulez regarder des fichiers dans un répertoire où des fichiers sont ajoutés et supprimés, ce script n'aide pas. Il est cependant utile lorsque vous n'utilisez pas de paramètres développés. :)
Code Commander

@CodeCommander, je pense que vous vous trompez. Bash (comme sh) se développe *sans le passer à la commande que vous exécutez. Essayez de courir: mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*dans une seule fenêtre. Pendant que cela fonctionne, vous pouvez touch /tmp/zz/bardans une autre fenêtre. Voyez si votre "montre" voit le changement, dans la première fenêtre. Je ne pense pas que ce sera le cas. Ce n'est pas pour moi. Cela n'a rien à voir avec Ubuntu vs OSX ou Linux vs Unix, c'est le comportement de bashlui - même.
ghoti

1
@ghoti, vous avez raison. Je me trompais. Même avec la commande Linux watch, vous devez utiliser des guillemets: watch "ls -l /tmp/zz/*"mais si vous vous souvenez d'utiliser des guillemets, cela fonctionne également avec votre script. :)
Code Commander


6

Si la montre ne souhaite pas installer via

brew install watch

Il y a une autre version similaire / copie qui a installé et a fonctionné parfaitement pour moi

brew install visionmedia-watch

https://github.com/tj/watch


5

Ou, dans votre ~ / .bashrc

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

2

J'avais un problème similaire.

Quand j'ai googlé, je suis tombé sur ce lien récemment. Ce n'est pas exactement «installer le logiciel», obtenir simplement la commande binaire pour «regarder».

Et le lien est Get watch command for OSX


1

Voici une version légèrement modifiée de cette réponse :

  • vérifie les arguments valides
  • affiche un titre de date et de durée en haut
  • déplace l'argument "duration" comme premier argument, de sorte que des commandes complexes peuvent être facilement passées comme arguments restants.

Pour l'utiliser:

  • Enregistrer ceci dans ~/bin/watch
  • exécuter chmod 700 ~/bin/watchdans un terminal pour le rendre exécutable.
  • essayez-le en courant 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

Essaye ça:

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

pour éviter le scintillement lorsque votre commande principale prend un temps perceptible, vous pouvez capturer la sortie et effacer l'écran uniquement lorsqu'elle est terminée.

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

puis utilisez-le par: watch istats


0

Utilisez le gestionnaire de paquets nix !

Installez nix, nix-env -iA nixpkgs.watchet il devrait être disponible pour utilisation après avoir terminé les instructions d'installation (y compris l'approvisionnement . "$HOME/.nix-profile/etc/profile.d/nix.sh"dans votre shell).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.