GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Grep wird langsam beendet, nachdem eine Übereinstimmung gefunden wurde?

Ich versuche, ein Bash-Skript zu schreiben, das Btmon nach Geräteverbindungen abfragt. Ich habe eine funktionierende Lösung, aber sie ist absurd langsam, und es scheint, als ob das Problem darin besteht, dass grep sehr langsam beendet wird, nachdem eine Übereinstimmung gefunden wurde (etwa 25 Sekunden). Was kann ich tun, um entweder grep zu beschleunigen oder ganz darauf verzichten?

#!/bin/bash
COUNTER=0
while :
  do
    until btmon | grep -m 1 '@ Device Connected'
      do :
    done
    let COUNTER=COUNTER+1
    echo on 0 | cec-client RPI -s -d 1
    sleep 5
    echo as | cec-client RPI -s -d 1
    until btmon | grep -m 1 '@ Device Disconnected'
      do :
    done
    let COUNTER=COUNTER-1
    if [ $COUNTER -eq 0 ];
      then echo standby 0 | cec-client RPI -s -d 1;
    fi
done

Bearbeiten:Zur Verdeutlichung btmon und ist ein Bluetooth-Überwachungstool, das Teil der Bluez-Suite ist, und cec-client ist ein Dienstprogramm, das mit libCEC geliefert wird, um (unter anderem) Befehle über den seriellen HDMI-CEC-Bus auszugeben.

Akzeptierte Antwort:

In:

cmd1 | cmd2

Die meisten Shells (die Bourne-Shell, (t)csh sowie yash und einige Versionen von AT&T ksh unter bestimmten Bedingungen, die die bemerkenswerten Ausnahmen darstellen) warten sowohl auf cmd1 und cmd2 .

In bash , das wirst du merken

sleep 1 | uname

kehrt nach einer Sekunde zurück.

In:

btmon | grep -m 1 '@ Device Disconnected'

grep wird beendet, sobald es ein Vorkommen des Musters gefunden hat, aber bash wird immer noch auf btmon warten .

btmon stirbt normalerweise an einer SIGPIPE, wenn es das nächste Mal nach grep in die Pipe schreibt zurückgekehrt ist, aber wenn es nie wieder etwas schreibt, würde es dieses Signal nie erhalten.

Sie könnten #! /bin/bash mit #! /bin/ksh93 da dies eine Shell ist, die mit bash kompatibel ist und eine, die nur auf die letzte Komponente einer Pipeline wartet. Dann in

btmon | grep -m 1 '@ Device Disconnected'

nach grep gibt zurück, btmon würde im Hintergrund laufen und die Shell würde mit dem Rest des Skripts fortfahren.

Wenn Sie btmon töten wollten sobald grep zurückgibt, POSIXly, könnten Sie so etwas tun:

sh -c 'echo "$$"; exec btmon' | (
   read pid
   grep -m1 '@ Device Disconnected' || exit
   kill "$pid" 2> /dev/null
   true)

Linux
  1. Wie führe ich Grep mit mehreren und Mustern aus?

  2. Wie stoppe ich den Find-Befehl nach dem ersten Match?

  3. Vorherige Zeile nach einer Musterübereinstimmung mit Sed drucken?

  4. Bewahren Sie die Färbung nach dem Piping von grep zu grep

  5. Vergleichen Sie zwei Zeichenfolgen in einer Zeile mit grep

Ermitteln der Prozessanzahl in Linux über die Befehlszeile

Wie verwende ich Regex Match End of Line in Windows?

Ausführbare Dateien mit ls und grep finden

Wie suche ich nach Inhalten nach dem Muster?

Linux sudo arbeitet langsam, nachdem der Hostname geändert wurde

Wie kann der Docker-Alpine-Container aufbewahrt werden, nachdem der Ausgang verwendet wurde?