2012-05-14 20 views
19

Escribo unos scripts de shell muy simples que examinarían el registro de todas las pruebas fallidas, e imprimiré todos los nombres del archivo de todos los archivos en el directorio actualComprueba el resultado de un comando en el script de 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 

Cuando ejecuto, me sale este error:

line 6: [0: command not found 

¿alguien tiene alguna idea de por qué?

Gracias!

+0

Usted desea mover el - ne al comienzo de la instrucción if – keyser

+4

le falta un espacio: '' if [$ (grep $ fi le failed.txt -c) -ne 0] '' – redShadow

Respuesta

25

[ es en realidad un comando en Linux (como bash o cat o grep).

$(grep $file failed.txt -c) es una sustitución de orden que en su caso evalúa a 0. Por lo tanto la línea ahora lee [0 -ne 0], que se interpreta como ejecutar un programa llamado [0 con argumentos -ne 0].

Lo que debe escribir en su lugar es [ $(grep $file failed.txt -c) -ne 0 ]. Los scripts de Shell requieren que haya espacios entre los corchetes cuadrados de apertura y cierre. De lo contrario se cambia el comando que se ejecuta (el cierre ] indica que no hay más argumentos para ser leídos.

Así que ahora el comando evalúa a [ 0 -ne 0 ]. Usted puede intentar ejecutar esto en su concha para ver qué pasa. [ salidas con un valor de 0 si la expresión es verdadera y 1 si es falso. se puede ver el valor de salida de eco $? (el valor de salida del último mandato a ejecutar).

+0

Aún así debe evitar el uso inútil de Backticks. http://partmaps.org/era/unix/award.html#backticks (vea el ejemplo por separado en particular). – tripleee

+0

@tripleee Un buen consejo, pero no diría que es especialmente relevante en este caso, ya que el resultado de grep en este caso es pequeño en comparación con ARG_LIMIT. Aunque como alguien señaló en otro comentario 'si grep $ file failed.txt -q' es la solución ideal. Por lo general, no me gusta usar redireccionamientos de salida ya que hacen que los guiones sean más difíciles de leer (más tokens para leer y procesar). – Dunes

+0

Oh, absolutamente; 'if grep -q' es a lo que me refería también. (¿Parece que tiene el patrón de búsqueda y el argumento del archivo invertidos?) – tripleee

6

en lugar de probar el recuento, se puede probar el código de retorno de grep:

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

Bueno, siempre podrías alinear todo el guión. 'gato falló.txt | xargs ls -f1 2>/dev/null' – Dunes

+3

Obtienes un poco de eficiencia usando 'grep -q' - si hay una coincidencia, grep sale inmediatamente. –

+1

Tenga en cuenta que la redirección '&>' no es posix. Bash lo interpretará de la misma manera que '>/dev/null 2> & 1', pero no todas las shells lo harán. (por ejemplo, dash invocará el grep en segundo plano y truncará/dev/null) –

1

El guión puede ser

#!/bin/sh 

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

o, como una sola línea en el usuario historial de comandos shell:

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

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

Cuestiones relacionadas