2017-01-31 1 views
0

Ich schreibe dieses Skript, das nach dem Smart-Test einen Fehler erkennen soll. Aber ich kann nicht erkennen, dass es einen Fehler gibt, oder natürlich nicht.Bash: Komplexer Befehl in if-Anweisung

if [[ smartctl --log=selftest /dev/sda | awk 'NR>7 {print $4,$5,$6,$7}' | sed 's/offline//g; s/00%//g' != *"Completed without error"* ]; then 
echo "No error detected" 
else echo "Error detected" 
fi 

Ausgang:

./test.sh: line 19: conditional binary operator expected 
./test.sh: line 19: syntax error near `--log=selftest' 
./test.sh: line 19: `if [[ smartctl --log=selftest /dev/sda | awk 'NR>7 {print $4,$5,$6,$7}' | sed 's/offline//g; s/00%//g' != *"Completed without error"* ]]; then' 

So offensichtlich etwas falsch ich tue. Aber alle Tutorials sagen zwei [[]] Dinger, aber ich denke, der Befehl ist ziemlich komplex, es funktioniert nicht ... Wie kann ich es zum Laufen bringen?

+1

'[[]]' ist ein spezifischer Befehl, nicht Teil der allgemeinen 'if'-Syntax. Wenn Sie diesen Befehl nicht ausführen möchten, fügen Sie ihn nicht in Ihre Syntax ein. –

+0

Stattdessen müssen Sie die von der Pipeline ausgegebene Zeichenfolge erfassen, um sie mit dem angegebenen Muster zu vergleichen. – chepner

+0

Entfernen der '[[]]' Ich bekomme 'sed: kann nicht lesen! =: Keine solche Datei oder Verzeichnis sed: kann nicht lesen * Fertig ohne Fehler *: Keine solche Datei oder Verzeichnis' – Florius

Antwort

2

Wenn Sie einen Teil Vergleich machen wollen, müssen Sie eine Zeichenfolge übergeben auf der linken Seite der = oder != Betreiber [[ ]].

Eine Befehlssubstitution, $(), ersetzt den enthaltenen Befehl durch seinen Ausgang und gibt Ihnen eine einzige Zeichenfolge, die auf diese Weise verglichen werden kann.

Das heißt:

smartctl_output=$(smartctl --log=selftest /dev/sda | awk 'NR>7 {print $4,$5,$6,$7}' | sed 's/offline//g; s/00%//g') 
if [[ "$smartctl_output" != *"Completed without error"* ]; then 
    : ...put your error handling here... 
fi 

oder, etwas weniger leserlich:

if [[ "$(smartctl --log=selftest /dev/sda | awk 'NR>7 {print $4,$5,$6,$7}' | sed 's/offline//g; s/00%//g')" != *"Completed without error"* ]; then 
    : ...put your error handling here... 
fi 
+0

Okay, das funktioniert, freundlich aus .. Ich bin mir nicht sicher, mit was der if-Fehler jedoch vergleicht ... Es heißt Fehler erkannt, obwohl es keine gibt. Stimmt etwas nicht mit dem '! = *" Completed ohne Fehler "*' Vergleich? [root @ operations ~] # ./test.sh Fehler erkannt [root @ operations ~] # smartctl --log = selbsttest/dev/sda | awk 'NR> 7 {print $ 4, $ 5, $ 6, $ 7}' | sed 's/offline // g; s/00% // g ' Fertig ohne Fehler Fertig ohne Fehler – Florius

+0

'deklarieren Sie -p smartctl_output', um den Inhalt der Variablen eindeutig zu drucken. –

+0

Okay, verstanden. Ich dachte eigentlich nicht daran, es zu einer Variable zu machen, ich dachte zu komplex! Danke, dass du mir nochmal einen Blick darauf gegeben hast! – Florius

2

Sie verwirrend Dinge sind. Wenn der zu testende Befehl smartctl lautet, ersetzen Sie ihn nicht durch [[. Du willst beides oder nicht beides. (Siehe auch zum Beispiel Bash if statement syntax error)

Wie auch immer, kochend awk durch sed und dann die Schale mit dem Ergebnis zu vergleichen, um eine andere Zeichenfolge wie eine extrem Umwegen scheint Dinge zu tun. Der Weg zur Kommunikation mit if ist die Rückgabe eines Nicht-Null-Exit-Codes für einen Fehler.

if smartctl --log=selftest /dev/sda | 
    awk 'NR>7 { if ($4 OFS $5 OFS $6 OFS $7 ~ /Completed without error/) e=1; exit } 
     END { exit 1-e }' 
then 
    echo "No error detected" 
else 
    echo "Error detected" 
fi 
+0

Ihr Befehl wird immer 1 beenden, obwohl Sie 'exit 0' vor dem' END'-Block haben, z. B. dieses 'echo 1 | awk '{exit 0} END {exit 1}'; echo $? ' –

+1

Sie können etwas tun, um zu korrigieren,' awk 'BEGIN {e = 1} NR> 7 {if ($ 4 OFS $ 5 OFS $ 6 OFS $ 7 ~/Ohne Fehler abgeschlossen /) e = 0} END {exit e && 1} '' –

+0

Das funktioniert! Hat eine Frage, wenn die Ausgabe zum Beispiel Fehler auf Disk/dev/sda gibt, wird es immer noch kein Fehler erkannt, weil es das Wort "Fehler" liest? Oder vergleicht es nur mit der vollständigen Zeichenfolge '/ Completed ohne Fehler /'? – Florius