it-swarm.com.de

Bash-Skript, das das Ändern von Echtzeitwerten von Befehlen zeigt

Auf einem Linux-Computer habe ich eine Reihe von Befehlen, die numerische Werte für den Zustand verschiedener Sensoren bieten.

Der Aufruf dieser Befehle ähnelt dem folgenden:

$ command1
5647
$ command2
76
$ command3
8754

Diese Werte ändern sich in Echtzeit, und jedes Mal, wenn ich den Status eines dieser Werte überprüfen möchte, muss ich den Befehl neu starten ... Dies nützt mir nichts, da ich beide Hände benötige, um die Hardware zu manipulieren.

Mein Ziel ist es, ein einfaches Bash-Skript zu erstellen, das diese Befehle aufruft und den Wert wie folgt aktualisiert (in Echtzeit asynchron oder alle x Sekunden aktualisiert):

$ ./myScript.sh
command1: x
command2: y
command3: z
command4: v

Wobei x, y, z und v die sich ändernden Werte sind.

Bash ermöglicht dies einfach und effizient? oder sollte ich mich dafür entscheiden, es in einer anderen Sprache wie Python zu tun?

UPDATE mit mehr Infos:

Mein aktuelles Skript lautet:

#!/bin/bash
echo "Célula calibrada: " $(npe ?AI1)
echo "Anemómetro: " $(npe ?AI2)
echo "Célula temperatura: " $(npe ?AI3)
echo "Célula temperatura: " $(npe ?AI4)

npe ist ein Beispielbefehl, der den numerischen Wert zurückgibt. Ich erwarte eine Ausgabe wie diese:

(enter image description here

Diese Ausgabe bekomme ich mit dem Befehl watch -n x ./myScript.sh, wobei x der Aktualisierungswert von Sekunden ist. Wenn ich mein Skript so bearbeite:

#!/bin/bash
while sleep 1; do
   clear; # added to keep the information in the same line 
   echo "Célula calibrada: " $(npe ?AI1);
   echo "Anemómetro: " $(npe ?AI2);
   echo "Célula temperatura: " $(npe ?AI3);
   echo "Célula temperatura: " $(npe ?AI4);
done

Ich bekomme meine Ausgabe mit einem nervigen Flackern:

(enter image description here

8
balon

Es kann schwierig sein, eine Echtzeitlösung in Bash zu implementieren.

Es gibt viele Möglichkeiten, ein Skript einmal in X Sekunden auszuführen. Sie können watch verwenden. Ich nehme an, Sie haben bereits myScript.sh verfügbar. Ersetzen Sie X durch die Anzahl der Sekunden, die Sie benötigen.

  1. watch -n X ./myScript.sh

  2. while sleep X; do ./myScript.sh; done

    upd. Um die Uhr zu emulieren, möchten Sie möglicherweise den Bildschirm zwischen den Iterationen löschen. Im Skript sieht es folgendermaßen aus:

    while sleep X; do 
       clear; 
       command1;
       command2;
    done
    
  3. fügen Sie dem Skript selbst eine der oben genannten Optionen hinzu.

11
rush

Mit tput cup 0 0 Können Sie den Cursor nach oben links auf dem Bildschirm senden. clear einmal.

#!/bin/bash
clear
while sleep 1; do
    tput cup 0 0
    printf "%21s %6d    \n" \
      "Célula calibrada: "   $(npe ?AI1) \
      "Anemómetro: "         $(npe ?AI2) \
      "Célula temperatura: " $(npe ?AI3) \
      "Célula temperatura: " $(npe ?AI4)
done
14
glenn jackman

Ich gehe davon aus, dass das Flimmern darauf zurückzuführen ist, dass Ihre Befehle einen Moment brauchen, um ihre Werte zurückzugeben. Dies ist meine übliche Problemumgehung:

cmds(){
  echo "Célula calibrada: " $(npe ?AI1);
  echo "Anemómetro: " $(npe ?AI2);
  echo "Célula temperatura: " $(npe ?AI3);
  echo "Célula temperatura: " $(npe ?AI4);
}

while true; do
  out="$(cmds)"
  clear
  echo "$out"
  sleep 1
done

Die Idee ist, dass wir den Bildschirm im letztmöglichen Moment löschen.

9
bxm

Wenn Sie clear unmittelbar nach dem sleep und nicht unmittelbar zuvor verwenden, können Sie die Ausgabe leichter lesen:

#!/bin/sh
while sleep 1
do
   clear
   echo "Célula calibrada: " $(npe ?AI1)
   echo "Anemómetro: " $(npe ?AI2)
   echo "Célula temperatura: " $(npe ?AI3)
   echo "Célula temperatura: " $(npe ?AI4)
done

Allerdings würde ich die Schleife hier entfernen und watch verwenden, um das Skript wiederholt auszuführen. Das ist eine flexiblere Zusammensetzung einzelner Werkzeuge.

5
Toby Speight

Sie können es genau in Bash tun. Wenn der Text immer noch blinkt, haben Sie die vorherigen Antworten nicht vollständig gelesen.

Sie müssen clear den Bildschirm vorher Sie geben die neuen Werte wieder, nicht danach.

3
Paul_Pedant

Sie sind: Anzeigen einer Zeile und Ausführen des Befehls zum Anzeigen der nächsten.

Sie müssen: alle Befehle ausführen (ohne die Anzeige zu berühren) und die Ergebnisse in 4 Variablen speichern, dann diese 4 Ergebnisse auf einmal löschen und anzeigen.

Wenn ich Ihr eigenes Skript ändere, versuchen Sie:

#!/bin/bash
while sleep 1; do
    # facultative?#  tput cup 0 0
    ccab="$(npe ?AI1)"
    cane="$(npe ?AI2)"
    ctemp="$(npe ?AI3)"
    ctemp2="$(npe ?AI4)"
    clear
    printf "%21s %6d    \n" \
      "Célula calibrada: "   "$ccab" \
      "Anemómetro: "         "$cane" \
      "Célula temperatura: " "$temp" \
      "Célula temperatura: " "$temp2"
done

Hier erfolgt die lange Ausführung der 4 Anforderungen ohne Änderung der Anzeige, dann wird die Anzeige sehr schnell aktualisiert und auf einmal mit den 4 neuen Werten angezeigt.

2
Olivier Dulac

sie können alle Ihre Befehle mit etwas Schlaf-Timing in die while-Schleife einfügen. Im folgenden Beispiel lege ich alle 2 Sekunden Schlaf. Der Datumsbefehl wird also alle 2 Sekunden ausgeführt

#!/bin/bash

while (true)
do
        echo "Date & Time : $(date)"
        sleep 2
done
2
Kamaraj

Dies führt zu 50 Zeilen ohne Flackern, da tput verwendet wird, um jede Zeile separat zu aktualisieren. Ich habe zwischen jeder Reihe einen Schlaf von 0,01 gesetzt, um dies zu beweisen.

Wenn Sie das Skript mit arg y ausführen, sehen Sie Beispiele dafür, wie Ihr Terminalfenster den Cursor positioniert. Ich habe meine Fluchten im Echo fest codiert. Ihre kann anders sein. Aus Gründen der Portabilität sollten Sie tput verwenden, um die Sequenzen dynamisch zu generieren. Für die Leistung sollten Sie alle Eingabesequenzen, die Sie jemals für Ihre App benötigen, im Voraus abrufen und in der Shell speichern. Wenn Sie den festen Text einmal installiert haben, ändern Sie einfach die variablen Teile.

Beachten Sie, dass die Bildschirmpositionen in tput args bei (0, 0) beginnen. Außerdem werden führende Nullen in Bildschirmbefehlen als oktal interpretiert, weshalb ich die sichtbare Zeilennummer mit printf neu formatiere. Es ist auch höflich, den Cursor nach dem Aktualisieren aus dem Weg zu räumen (wie (0,0)).

#! /bin/bash

#.. See what a CUrsor Position is on the current terminal.
[[ "${1}" == y ]] && {
    for r in {0..19}; do
        tput cup ${r} 15 | od -An -t ax1
    done
    exit
}

tput clear

while sleep 1; do
    for k in {1..50}; do
        sleep 0.01
        RW=$( printf '%.2d' ${k} )
        TS=$(date "+%Y-%m-%d %H:%M:%S.%N")
        echo -n -e "\e[${k};1H${RW}  ${TS}"
    done
    echo -n -e "\e[52;1H"
done
2
Paul_Pedant

Geben Sie nach Ablauf des Ruhezustands eine Rücktaste wieder und zeigen Sie einen Wert erneut an. Dies setzt voraus, dass Sie sich auf einem Terminal befinden, auf dem Escape-Codes, die Breite und die Linien des Terminals angezeigt werden können. Dies funktioniert jedoch als schnelle Aufnahme. Beispiel: Spinner anzeigen, während auf den Abschluss eines Prozesses gewartet wird

1
Matthias Š

Sie können eine Schleife in bash einrichten - Konstrukt ist while true; do ....; done wo .... ist dein Befehl. Sie müssten Ctrl+C um es zu stoppen.

Sie müssen in der Schleife schlafen, sonst schreit es einfach herum und verbraucht Ihre gesamte CPU-Zeit. Die Sekunden zum Schlafen sind ein Kompromiss zwischen dem Abrufen aktueller Zahlen und zu viel Ausgabe.

Wenn Sie die Ausgabebreiten über den Bildschirm in festen Spalten formatieren (verwenden Sie den Befehl printf), können Sie Variationen leichter erkennen.

Ich würde wahrscheinlich die Ausgabe von all dem in eine Datei senden (Umleitung nach dem "erledigt"), damit Sie sie anschließend nach Belieben untersuchen, vielleicht sogar grafisch darstellen oder Statistiken erstellen können. Sie können ein tail -f Befehl in einem anderen Fenster, in dem die neuesten Daten angezeigt werden, die der Datei hinzugefügt wurden, damit Sie sie auch sehen können.

Sie können auch einen Befehl date in die Schleife einfügen, um jede Zeile mit einem Zeitstempel zu versehen, falls die Intervalle zwischen den Daten wichtig sind.

Poste erneut, wenn etwas mehr Fleisch auf den Knochen benötigt.

1
Paul_Pedant