Bash | Mehrere Zahlen/Zeilen vergleichen

BlackForest

Azubi - FiSy
Hallo zusammen,

ich schreibe aktuell ein Bash-Skript mit welchen ich S.M.A.R.T-Werte vergleichen möchte. Ziel ist es das ein mal die Woche ein long self-test läuft, es existieren bei jedem Durchlaufen des Skript's zwei .txt-Dateien, in beiden sind nur die VALUE's aufgelistet, also wie folgt:

Code:
1.txt:          2.txt:
-------         -------
100             70
80              80
99              60
200             200

1.txt ist das Ergebnis vom letzten Test, 2.txt vom aktuellen.

Wir haben als Schwellwert 23 gewählt, daher muss jede Zeile verglichen werden und wenn in einer Zeile der Wert sich um 23 oder mehr verschlechtert hat, soll eine E-Mail verschickt werden.

Wie realisiere ich die Prüfung am einfachsten?

Danke!
 

DeaD_EyE

Blog Benutzer
In der Shell könntest du mit
Code:
for line in $(cat 1.txt); do foo; done
einfach über die Zeilen iterieren. Ist schon lange her...
Keine Ahnung wie man über zwei Dateien in einem Rutsch iteriert.
Wahrscheinlich gar nicht.


Damit ich nicht lange denken musste, hab ich es in Python geschrieben (ist so schön einfach)
Code:
def delta_smart_values(file1, file2, threshold=23):
    delta = [] #
    for f1, f2 in zip(open(file1), open(file2)): # here is the magic
        x = abs(int(f1) - int(f2))
        delta.append(x)
    return delta

Die Funktion würde dir dann die Differenz als positiven Wert in einer Liste ausgeben: [30, 0, 39, 0]

So hast du schon mal die einzelnen Differenzen, die du später nutzen könntest.
Um jetzt ein True oder False rauszubekommen:

Code:
ergebnis = delta_smart_values('1.txt', '2.txt')
max(ergebnis) > 23
>>> True

Könnte man so schreiben:
Code:
  GNU nano 2.2.6                                   Datei: smart_ok.py

#!/usr/bin/env python
from __future__ import print_function
import sys

def delta_smart_values(file1, file2):
    delta = [] #
    for f1, f2 in zip(open(file1), open(file2)): # here is the magic
        x = abs(int(f1) - int(f2))
        delta.append(x)
    return delta

def main(file1, file2):
    if max(delta_smart_values(file1, file2)) > 23:
        return 1
    else:
        return 0

if __name__ == '__main__':
    if len(sys.argv) == 3:
        retval = main(sys.argv[1], sys.argv[2])
    else:
        print("Usage: {} file1 file2".format(sys.argv[0]))
        retval = 1
    sys.exit(retval)

Über Threshold:
Code:
deadeye@nexus:~/test$ python smart_ok.py 1.txt 2.txt || echo HDD brennt ab
HDD brennt ab

Darunter:
Code:
deadeye@nexus:~/test$ python smart_ok.py 1.txt 2.txt || echo HDD brennt ab
deadeye@nexus:~/test$
 

.A.

Probiers mal was in diese Richtung:
Code:
while read LINE; do VALUES1=(${VALUES1[@]} $LINE); done <1.txt
while read LINE; do VALUES2=(${VALUES2[@]} $LINE); done <2.txt
for i in $(seq 0 $(expr ${#VALUES2[@]} - 1)); do [ $(expr ${VALUES1[$i]} - ${VALUES2[$i]}) -ge 23 ] && echo "HDD ist hinüber" | mail -s "Dumm gelaufen" root; done
Ist hässlich, kann aber evtl. klappen.


@DeaD: Das cat braucht es nicht.
--
.A.
 
Last edited by a moderator:

elias5000

Site Reliability Engineer
Nen perl snippet wäre hässlicher xD
Das hängt davon ab, ob man Perl schreiben kann oder nicht. :p

Abgesehen davon bin ich als alter Perl-Hase der Ansicht, dass man anno 2015 keine neuen Sachen mehr in Perl schreibt und empfehle die von DeaD_EyE gepostete Lösung mit dem Python-Script.

Bash mag ein schöner Hammer sein aber das gestellte Problem ist kein Nagel.
 

BlackForest

Azubi - FiSy
@DeaD_EyE: Vielen Dank für deine Bemühung :)
Muss gestehen das Python noch "Neuland" für mich ist, ich hab's in einem ersten Test eben allerdings schon mit dem gewünschten Ziel zum Laufen gebracht. Muss mich jetzt noch etwas intensiver mit Python befassen, damit ich das gesamte Skript damit schreiben kann.

@.A.:
Auch an Dich vielen Dank! - Hat wunderbar geklappt und das Ziel ist damit erreicht. Langfristig sollte ich das (wie oben bereits erwähnt) in Python schreiben.

Nen perl snippet wäre hässlicher xD

Gut, das ich mich mit Perl nicht befassen muss. Zumindest aktuell..

Das hängt davon ab, ob man Perl schreiben kann oder nicht. :p

Abgesehen davon bin ich als alter Perl-Hase der Ansicht, dass man anno 2015 keine neuen Sachen mehr in Perl schreibt und empfehle die von DeaD_EyE gepostete Lösung mit dem Python-Script.

Bash mag ein schöner Hammer sein aber das gestellte Problem ist kein Nagel.

Bestätigt das was ich bis jetzt über Perl gehört habe, tu mich mit der Anwendung von Python noch recht schwer, mir fällt es irgendwie einfacher unnötig komplexe Bash-Skripte zu bauen.. Muss mich definitiv jetzt mal massiv mit Python befassen!
 

Fusl

Blog Benutzer
Code:
› pr -m -t 1.txt 2.txt | awk '($1-$2)>22 {print "Zeile "NR": "$1" -> "$2}'
Zeile 1: 100 -> 70
Zeile 3: 99 -> 60
 

DeaD_EyE

Blog Benutzer
Du musst jetzt nicht unbedingt Python lernen, die Absicht finde ich aber gut :)
Für die Grundkenntnisse habe ich 3 Tage gebraucht. Die Lernkurve ist steil. Ich bin halt ein Python-Fan.

Python ist ursprünglich entstanden, um Tasks zu erledigen, die mit der Shell nur schwer zu lösen waren. Die Sprache ist von Anfang an für OOP ausgelegt. Viele haben beigesteuert und mittlerweile ist Python überhaupt nicht mehr wegzudenken. Die stdlib ist sehr groß. Was man dort nicht findet, bekommt man über pypi (eine Art Modulrepository für Python). Die Kritik, dass Python als Sprachelement auch Leerzeichen nutzt, stieß bei vielen auf Kritik. Die Kritiker nutzen mittlerweile selbst Python oder haben es nie ausprobiert.

Contra:
  • Kein Multithreading. Der Interpreter nutzt zwar OS Threads, kann aber aufgrund des GIL (Global Interpreter Lock) nur eine Instruktion nach der anderen ausführen. Es gibt aber Lösungen.
  • Software zu verteilen ist nicht einfach mit Python. Es gibt einiges, was man falsch machen kann.
  • Python2.x ist inkompatibel zu Python 3.x. Auf vielen Systemen ist standardmäßig noch Python 2.7 oder sogar nur Python 2.6 (Red Hat) installiert. Die wichtigen Pakete sind auch für Python 3 verfügbar. Möchte man aber so wenig wie möglich auf dem Hostrechner hand anlegen, beißt man in den sauren Apfel und nutzt weiterhin Python 2.7 und wenn möglich ohne Abhängigkeiten. Die Wissenschaftler nutzten mittlerweile alle durchgängig Python 3, da die wichtigen Module wie z.B. Numpy und SciPi portiert worden sind.

Anfänger sollten trotz dessen mit Python 3 anfangen. Die Sprache ist einfach besser.

Auf meiner ToDo-Liste steht noch: C, Go, Haskell

PS: Perl spielt immer noch eine sehr wichtige Rolle. Deinstalliere mal den Perl-Interpreter unter Linux und dann guck nochmal nach, was alles nicht mehr geht. Ich meine gelesen zu haben, dass sogar Perl 7 bald released werden soll. Perl ist ne coole Sprache. Sie ist kompakter als Python, sieht dafür aber auch manchmal für Menschen, die kein Perl können, eher nach einer AES-Verschlüsselung aus :-D
 

Joe User

Zentrum der Macht
@Fusl

Der Schwellwert sollte in beide Richtungen abgefangen werden:
Code:
pr -m -t 01.txt 02.txt | awk '($1-$2)>22||($2-$1)>22 {print "Zeile "NR" knackt Schwellwert"}'
 

nexus

Well-Known Member
@DeaD_EyE:
Du hast ja hier schon öfters Problemlösungen in Python gepostet, die meist genauso simpel wie elegant sind. Hast du zufällig eine gute Dokumentation zu Python, die für Neueinsteiger eine Empfehlung wert wäre?
 

Joe User

Zentrum der Macht
Nicht jeder S.M.A.R.T.-Wert steigt bei Verschlechterung und der OP verschweigt ja welche konkreten Werte er da vergleicht ;)

Unabhängig davon sollte der OP sich mal die Manpage zu "smartctl --attributes" bezüglich VALUE, WORST und THRESH sorgfältiger durchlesen und seine Idee gegebenefalls nochmal komplett überdenken. Da wurde höchstwahrscheinlich Einiges falsch verstanden, sonst wäre es nicht zu einem pauschalen Schwellwert von 23 gekommen...
 

DeaD_EyE

Blog Benutzer
Da ich ein Python-Fan bin, hab ich gestern bisschen was zu Python geschrieben. Ich habe vergessen zu speichern (kopf>tisch)

Es gibt auch Nachteile wie in jeder anderen Sprache auch. Multithreading (GIL) gibt es nicht. Da muss man z.B. drum herum arbeiten (Multiprocessing, Async). Nichts desto trotz kann man in Python schnell Prototypen entwickeln und die stdlib ist recht groß. Infos findest du über google. Das Buch "Python the hard way" soll sehr gut sein. Ich hab mir noch writing idomatic python gekauft, um von anfang an mich an den Coding-Style zu halten. Wenn man das einmal verinnerlicht hat, geht das automatisch. Es gibt noch ein inoffizielles deutsches Forum: python-forum.de

Den Beispielcode, den ich gepostet habe, berechnet Delta immer als positiven Wert. Damit lässt sich dann die Abweichung in beide Richtungen abfragen. Ich persönlich lege überhaupt keinen Wert mehr auf die S.M.A.R.T Werte. Ich hatte immer das Pech, dass meine Festplatten vor dem Alarm kaputt gingen (keine Überscheitungen der Werte). Ich rechne einfach damit, dass rotatorische Medien nach 1-2 Jahren hinüber sind. Früher kann natürlich auch etwas kaputt gehen.

PS: In irgendeinem Talk hatte ich mal gehört, dass da einer aus Langeweile einen Flugsimulator in AWK gebastelt hat...muss schon lange her sein
 
Last edited by a moderator:

elias5000

Site Reliability Engineer
Ich rechne einfach damit, dass rotatorische Medien nach 1-2 Jahren hinüber sind.
Am besten behandelt man generell alle Speichermedien (egal ob Solid State oder mit rotierenden Scheiben) so als wenn sie innerhalb der nächsten Nanosekunde unrettbar ausfallen würden.

Ich habe mittlerweile sehr viele Festplatten ausfallen sehen und ich kann mich nicht konkret daran erinnern, dass eine Platte sich frühzeitig angekündigt hätte (und ich habe immer SMART-Tests konfiguriert). Die meisten Ausfälle fielen erst durch I/O-Fehler in den Logs auf.

Klar kann man auch SMART angucken aber viel wichtiger ist es, den Ausfall einer Platte zeitnah zu bemerken und entsprechende Vorkehrungen zu haben, die den Ausfall der Platte zu einer unkritischen Routine-Angelegenheit machen (RAID-Mirror, Backup, vorhandener Recovery-Plan).

Gerade ein Recovery-Plan ist wichtig. Das beste Backup nützt nichts, wenn im Desaster-Fall erstmal unklar ist, wie man vom Backup eigentlich wieder zu einem laufenden System kommt.
 

nexus

Well-Known Member
Das Buch "Python the hard way" soll sehr gut sein. Ich hab mir noch writing idomatic python gekauft, um von anfang an mich an den Coding-Style zu halten. Wenn man das einmal verinnerlicht hat, geht das automatisch. Es gibt noch ein inoffizielles deutsches Forum: python-forum.de

Danke für die Buchempfehlungen. Da muß ich meinem Finanzminister (gemeint ist natürlich meine Frau) jetzt klarmachen, daß ich ein vorgezogenes Weihnachtsgeschenk brauche :D
Das Forum ist ja sehr umfangreich, macht aber nach ein bissel Rumklicken schon einen guten ersten Eindruck :)
 
Top