2009-02-21 7 views
6

En un script bash, debo verificar la existencia de varios archivos.Bash: ¿Cómo puedo verificar si existen ciertos archivos?

sé una manera incómoda para hacerlo, que es la siguiente, pero eso significaría que mi programa principal tiene que estar dentro de esa estructura anidada fea:

if [ -f $FILE1 ] 
then 
if [ -f $FILE2 ] 
then 
    echo OK 
    # MAIN PROGRAM HERE 
fi 
fi 

La versión siguiente no funciona:

([ -f $FILE1 ] && [ -f $FILE2 ]) || (echo "NOT FOUND"; exit 1) 
echo OK 

imprime

NOT FOUND 
OK 

¿hay una manera elegante de hacer esto bien?

ACTUALIZACIÓN: Ver la respuesta aceptada. Además, en términos de elegancia me gusta Jonathan Leffler's answer:

arg0=$(basename $0 .sh) 
error() 
{ 
    echo "$arg0: [email protected]" 1>&2 
    exit 1 
} 

[ -f $FILE2 ] || error "$FILE2 not found" 
[ -f $FILE1 ] || error "$FILE1 not found" 

Respuesta

10

¿Qué tal

if [[ ! (-f $FILE1 && -f $FILE2) ]]; then 
    echo NOT FOUND 
    exit 1 
fi 

# do stuff 
echo OK 

Ver help [[ y help test de las opciones que pueden utilizarse con las pruebas de estilo [[. Lea también this faq entry.

Su versión no funciona porque (...) genera un nuevo subcuadro en el que se ejecuta exit. Por lo tanto, solo afecta a esa subcadena, pero no a la secuencia de comandos de ejecución.

Lo siguiente funciona en su lugar, ejecutando los comandos entre {...} en el shell actual.

También debería tener en cuenta que debe citar las dos variables para asegurarse de que no haya una expansión indeseada o división de palabras hecha (deben pasarse como un argumento a [).

[ -f "$FILE1" ] && [ -f "$FILE2" ] || { echo "NOT FOUND"; exit 1; } 
+0

Gracias, eso se ve bien. Solo el 'o' (||) debería ser un 'y' (&&), supongo. – Frank

+0

arreglado ya :) difícil con lógica en la noche :) –

4

Creo que está buscando:

if [ -f $FILE1 -a -f $FILE2 ]; then 
    echo OK 
fi 

Ver man test para más detalles sobre lo que puede poner dentro de la [ ].

+0

+1 para 'prueba de hombre'. ¡Gracias! – binarybob

3

Se pueden listar los archivos y comprobar que en un bucle:

file_list='file1 file2 wild*' 
for file in $file_list; do 
    [ -f $file ] || exit 
done 

do_main_stuff 
1

por lo general utilizar una variante en:

arg0=$(basename $0 .sh) 
error() 
{ 
    echo "$arg0: [email protected]" 1>&2 
    exit 1 
} 

[ -f $FILE2 ] || error "$FILE2 not found" 
[ -f $FILE1 ] || error "$FILE1 not found" 

No hay virtud en particular en la toma de la secuencia de comandos shell tener una sola salida punto - no hay daño tampoco, pero los errores fatales también pueden terminar el script.

El único punto de debate sería si diagnosticar tantos problemas como sea posible antes de salir, o si simplemente diagnosticar el primero. En promedio, diagnosticar solo el primero es mucho más fácil.

Cuestiones relacionadas