2012-05-14 8 views
19

Ich schreibe eine sehr einfache Shell-Skripts, die das Protokoll aller fehlgeschlagenen Tests betrachtet und den gesamten Namen aller Dateien im aktuellen Verzeichnis, die im Protokoll enthalten sind, ausgedrucktÜberprüfen Sie die Ausgabe eines Befehls in Shell-Skript

1 #! /bin/sh 

2 for file in * 
3 do 
4  echo "checking: $file" 
5  if [$(grep $file failed.txt -c) -ne 0] 
6  then 
7   echo "$file FAILED" 
8  fi 
9 done 

Als ich es ausführen, bekomme ich diesen Fehler:

line 6: [0: command not found 

Hat jemand eine Idee, warum?

Danke !!

+0

Sie wollen die bewegen - ne an den Anfang der if-Anweisung – keyser

+4

fehlt ein Leerzeichen: '' if [$ (grep $ fi le failed.txt -c) -ne 0] '' – redShadow

Antwort

25

[ ist eigentlich ein Befehl in Linux (wie bash oder cat oder grep).

$(grep $file failed.txt -c) ist ein Befehl Substitution, die auf 0 ausgewertet, in Ihrem Fall also jetzt die Linie liest [0 -ne 0], die -ne 0] mit Argumenten [0 genannt, ein Programm als laufen interpretiert wird.

Was Sie stattdessen schreiben sollten, ist [ $(grep $file failed.txt -c) -ne 0 ]. Shell-Skripts erfordern Leerzeichen zwischen den öffnenden und schließenden eckigen Klammern. Andernfalls Sie den Befehl ändern, die (das Schließen ausgeführt wird ] zeigt an, dass es keine weiteren Argumente zu lesen ist.

So, jetzt der Befehl an [ 0 -ne 0 ] auswertet. Sie können versuchen, diese in der Shell ausgeführt wird, um zu sehen, was passiert. [ Ausfahrten mit einem Wert von 0 wenn der Ausdruck wahr ist und 1 wenn es falsch ist. Sie haben den Exit-Wert $? von Echo sehen (der Ausgangswert des letzten Befehls ausgeführt werden).

+0

Sie sollten immer noch die unbrauchbare Verwendung von Backticks vermeiden. http://partmaps.org/era/unix/award.html#backticks (siehe das separate Beispiel). – tripleee

+0

@tripleee Guter Rat, aber ich würde in diesem Fall nicht besonders relevant sagen, da die Ausgabe von grep in diesem Fall wahrscheinlich winzig im Vergleich zu ARG_LIMIT ist. Obwohl jemand in einem anderen Kommentar darauf hingewiesen hat, dass "grep $ failure.txt -q" die ideale Lösung ist. Ich bin generell nicht scharf darauf, Output-Weiterleitungen zu verwenden, da sie das Lesen von Skripten erschweren (mehr Tokens, die ich lesen und verarbeiten kann). – Dunes

+0

Oh, absolut; 'grep -q' ist auch, worauf ich hinauswollte. (Sie scheinen das Suchmuster und das Dateiargument umgekehrt zu haben?) – tripleee

6

Statt die Anzahl der Prüfung, Sie kann den Rückkehrcode von grep:

if grep -q $file failed.txt &>/dev/null 
0 testen
+0

Nun, Sie könnten immer eine Zeile das gesamte Skript auch. 'Katze ist fehlgeschlagen.txt | xargs ls -f1 2>/dev/null' – Dunes

+3

Mit 'grep -q' gewinnen Sie ein wenig Effizienz - wenn es eine Übereinstimmung gibt, wird grep sofort beendet. –

+1

Beachten Sie, dass die '&>' Umleitung nicht posix ist. Bash wird es genauso interpretieren wie '>/dev/null 2> & 1', aber nicht alle Shells. (z. B. strich wird grep im Hintergrund aufrufen und/dev/null abschneiden) –

1

Das Skript kann

#!/bin/sh 

for file in *; do 
    echo "checking: $file" 
    grep failed.txt $file && echo "$file FAILED" 
done 

oder als Einzeiler in Benutzer-Shell-Befehl Geschichte sein:

for file in *; do { echo "checking: $file" && grep failed.txt $file && echo "$file FAILED"; done

in man grep

EXIT STATUS
The exit status is 0 if selected lines are found, and 1 if not found. If an error occurred the exit status is 2. (Note: POSIX error handling code should check for '2' or greater.)

Verwandte Themen