2012-05-14 19 views
19

Sto scrivendo uno script di shell molto semplice che avrebbe esaminato il registro di tutti i test non riusciti e stampato tutto il nome di tutti i file nella directory corrente presenti nel registroControllare l'output di un comando nello script di shell

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 

Quando eseguire esso, ottengo questo errore:

line 6: [0: command not found 

qualcuno ha qualche idea del perché?

Grazie !!

+0

Si desidera spostare il - ne all'inizio della if-statement – keyser

+4

ti manca uno spazio: '' if [$ (grep $ fi le failed.txt -c) -ne 0] '' – redShadow

risposta

25

[ è in realtà un comando in linux (come bash o cat o grep).

$(grep $file failed.txt -c) è una sostituzione di comando che nel tuo caso valutato a 0. Così la linea ora legge [0 -ne 0], che viene interpretato come eseguire un programma chiamato [0 con argomenti -ne 0].

Quello che dovresti scrivere è invece [ $(grep $file failed.txt -c) -ne 0 ]. Gli script di shell richiedono che ci siano spazi tra le parentesi quadre di apertura e di chiusura. In caso contrario, si cambia il comando che viene eseguito (la chiusura ] indica che non ci sono più argomenti da leggere.

Così ora il comando restituisce [ 0 -ne 0 ]. Si può provare l'esecuzione di questo nella shell per vedere cosa succede. [ uscite con un valore di 0 se l'espressione è vera e 1 se è falso. si può vedere il valore di uscita facendo eco $? (il valore di uscita dell'ultimo comando da eseguire).

+0

Si dovrebbe comunque evitare l'uso inutile dei backtick. http://partmaps.org/era/unix/award.html#backticks (controlla in particolare l'esempio separato). – tripleee

+0

@ tripleo Un buon consiglio, ma non direi particolarmente rilevante in questo caso in quanto l'output di grep in questo caso è probabilmente piccolo rispetto a ARG_LIMIT. Anche se come qualcuno ha sottolineato in un altro commento 'se grep $ file failed.txt -q' è la soluzione ideale. Generalmente non mi piace usare i reindirizzamenti dell'output perché rendono gli script più difficili da leggere (più token da leggere e elaborare). – Dunes

+0

Oh, assolutamente; 'se grep -q' è quello che stavo ottenendo anche io. (Sembra che il pattern di ricerca e l'argomento del file siano invertiti?) – tripleee

6

Invece di testare il conteggio, è può testare il codice di ritorno di grep:

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

Bene, puoi sempre scrivere una riga per l'intero script. 'gatto fallito.txt | xargs ls -f1 2>/dev/null' – Dunes

+3

Ottieni un po 'di efficienza usando 'grep -q' - se c'è una corrispondenza, grep esce immediatamente. –

+1

Si noti che il reindirizzamento "&>" non è posix. Bash lo interpreterà come '>/dev/null 2> & 1', ma non tutte le shell lo faranno. (ad esempio, dash invocherà il grep in background e troncerà/dev/null) –

1

Lo script può essere

#!/bin/sh 

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

o, come un one-liner in utente cronologia dei comandi della shell:

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.)

Problemi correlati