comment bip sur l'événement tail -f

14

Je veux que mon PC émette un bip système à chaque événement de queue

J'ai la commande suivante

tail -f development.log | grep "something rare"

Existe-t-il un moyen simple de le canaliser vers quelque chose qui émet un bip? comme

tail -f development.log | grep "something rare" | beep

si oui, la sortie grep sera-t-elle toujours affichée?

Jakob Cosoroaba
la source
il y a un programme de bip avec est dans le référentiel par défaut pour debian et les variantes juste un bip d'installation apt-get, mais cela ne fonctionne pas avec la tuyauterie de cette façon
Jakob Cosoroaba

Réponses:

16

Définissez simplement ce beepqui suit:

beep() { read a || exit; printf "$a\007\n"; beep; }

Ensuite, vous pouvez utiliser votre commande:

tail -f development.log | grep "something rare" | beep
mouviciel
la source
1
désolé mais cela ne fonctionne pas, il n'émet aucun bip ou n'imprime rien
Jakob Cosoroaba
4
Bien que la sortie directe de tail -f soit immédiate, elle est mise en mémoire tampon dès qu'elle passe par un tube. Vous devez attendre suffisamment de "quelque chose de rare" avant d'observer quoi que ce soit.
mouviciel
Vous pouvez passer la sortie à travers sedou similaire (entre queue et grep) avec une expression rationnelle remplacer le something rareavec lui-même plusieurs fois. Le nombre de fois que cela doit être fait dépend de la quantité de tampon du tuyau.
David Spillett
6
@David - C'est une approche aléatoire. Si vous souhaitez annuler la mise en mémoire tampon des données transmises via un canal, utilisez l'une des méthodes décrites dans ces réponses: stackoverflow.com/questions/1000674/turn-off-buffering-in-pipe
2
En partant de la suggestion de @ nagul, voici l'invocation qui a fonctionné pour moi:tail -f development.log | stdbuf -oL -eL grep "something rare" | beep
GuitarPicker
10

L'écran GNU a une fonction intégrée pour émettre un bip lorsqu'une fenêtre donnée change: voir la section pertinente de la page de manuel .

Résumé du titre:

$ screen
$ tail -f yourfile.log    # inside the screen session
<C-a> M    # "Window 0 (bash) is now being monitored for all activity."

Comme indiqué dans les commentaires, cela émettra un bip à chaque nouvelle entrée de journal, pas seulement celles qui correspondent à "quelque chose de rare", donc cela ne fait pas tout à fait ce que l'OP a demandé. Encore une astuce utile pour connaître IMHO.

Vous pouvez tirer le meilleur parti des deux mondes en ouvrant deux screenfenêtres ( <C-a> cpour ouvrir une fenêtre, <C-a> <C-a>pour basculer entre deux fenêtres):

  1. surveillé, avec tail -f yourfile.log | grep 'something rare'
  2. sans surveillance, avec une plaine tail -f yourfile.log

Ensuite, vous pouvez vous asseoir en regardant le journal défiler dans la fenêtre 2, et vous obtiendrez un bip de la fenêtre 1 lorsque "quelque chose de rare" se produit.

screen est incroyablement polyvalent - je recommande fortement de le lire.

Sam Stokes
la source
1
Cela ne signifierait pas seulement "quelque chose de rare", n'est-ce pas?
1
Ce serait le cas si tout ce qui se passait dans cette fenêtre particulière était tail -f yourfile.log | grep something\ rareplutôt quetail -f logfile
David Spillett
Oups, je n'ai pas remarqué qu'il voulait seulement un bip something rare. Modifié pour refléter cela. Le grep fonctionnerait, mais il ne verrait pas le reste du journal, seulement les lignes rares - si je comprends bien, il veut pouvoir regarder le journal entier défiler, mais être alerté sur des événements spécifiques.
Sam Stokes, le
1

Vous pouvez empêcher la sortie d'être mise en mémoire tampon dans la commande grep. Voir man grep pour plus de détails.

Vous pouvez diriger la sortie grep vers un bip.

L'exemple suivant est tiré du bip de l'homme ...

   As part of a log-watching pipeline

          tail -f /var/log/xferlog | grep --line-buffered passwd | \
          beep -f 1000 -r 5 -s

Il y a beaucoup de bonnes choses dans ces manuels. Si seulement nous n'avions pas à les lire pour le trouver. ;-)

Un lecteur
la source
1

La commande watch a une option --beep, et vous pouvez également définir l'intervalle d'interrogation, mais la norme avec 2 sec devrait être ok

watch --beep 'tail development.log | grep "something rare"'
oanoss
la source
1
Remarque, watchfonctionne en exécutant votre paramètre / commande toutes les sections (intervalle), puis en envoyant les résultats à l'exécution précédente. Ainsi, vous voudrez utiliser la version normale de la commande tail, au lieu d'utilisertail -f
RyanWilcox
Cela n'a pas fonctionné pour moi (malgré l'ajout watch --beepet l'enveloppement de ma queue / grep, je n'ai toujours pas reçu de bip).
machineghost
1

Vous pouvez utiliser sed pour ajouter le contrôle-G comme suit:

tail -f myFile | sed "s/.*/&\x07/"

ou simplement sur des lignes rares, sans utiliser grep, comme suit:

tail -f myFile | sed -n "/something rare/s/.*/&\x07/p"

qui dit: sur les lignes où se produit quelque chose de rare, s tout ubstitute pour la même chose avec le contrôle-G clouée sur la fin et l' impression (mais ne pas imprimer les lignes qui ne correspondent pas ). Fonctionne très bien!

Mi5ke
la source
0

Hm, délicat. On pourrait peut-être faire quelque chose comme ça?

for i in `find | grep 7171`; do beep; echo $i; done

Ou dans votre cas

for i in `tail -f development.log | grep "something rare"`; do beep; echo $i; done

Il semble cependant faire un tampon. Je vais voir s'il existe un moyen de désactiver cette mise en mémoire tampon par la forboucle.

Apparemment, vous devriez pouvoir ajuster la mise en mémoire tampon du tuyau à l'aide de ulimit -pmais cela continue de me plaindre de l'argument invalide. J'ai également trouvé un article qui prétend que vous devez recompiler le noyau pour modifier cette limite.

Ivan Vučica
la source
0

Dans un travail précédent, je ne pouvais pas obtenir un veilleur fiable avec commande-fu juste, alors j'avais un script d'emballage comme celui ci - dessous, qui a contrôlé le fichier toutes les poll_duration secondes et les nouvelles lignes rassemblés de pour l'expression intéressé.

#!/bin/bash

file=$1
phrase=$2
poll_duration=$3

typeset -i checked_linecount
typeset -i new_linecount
typeset -i new_lines
let checked_linecount=new_linecount=new_lines=0
echo "Watching file $file for phrase \"$phrase\" every $poll_duration seconds"

while [ 1 ]
do
        let new_linecount=`wc -l $file| awk '{print $1}'`
        if [[ $new_linecount > $checked_linecount ]]; then
                let "new_lines = $new_linecount-$checked_linecount"
                head --lines=$new_linecount "$file" | tail --lines=$new_lines | grep "$phrase" && beep
                let checked_linecount=$new_linecount
        fi
        sleep $poll_duration
done

C'était sur une machine Unix. Sous Linux, vous pouvez faire mieux en utilisant son interface inotify filewatcher. Si ce paquet ( inotify-tools sur Ubuntu) est présent, remplacez

sleep $poll_duration 

avec

inotifywait -e modify "$file"  1>/dev/null 2>&1

Cet appel bloque jusqu'à ce que le fichier soit modifié. La version bloquante est presque aussi efficace que ce que vous obtiendriez avec la tail -fversion si le tube pouvait être configuré pour fonctionner sans mise en mémoire tampon.

Remarque: Le script fait d'abord un head --lines=$new_linecountpour s'assurer que les lignes ajoutées au fichier après l'avoir vérifié ne biaisent pas le morceau du fichier qui est vérifié dans cette boucle.


la source