Cómo verificar si existe un archivo en Linux Bash Scripts

Publicado: 2022-08-18
Computadora portátil Linux que muestra un indicador de bash
fatmawati achmad zaenuri/Shutterstock.com

Si un script de Linux Bash se basa en la presencia de ciertos archivos o directorios, no puede simplemente asumir que sí. Necesita comprobar que están definitivamente presentes. Así es como se hace.

No asumas nada

Cuando está escribiendo un guión, no puede hacer suposiciones sobre lo que está y lo que no está presente en una computadora. Eso es doblemente cierto si el script se va a distribuir y ejecutar en muchas computadoras diferentes. Tarde o temprano, la secuencia de comandos se ejecutará en una computadora que no cumpla con sus suposiciones y la secuencia de comandos fallará o se ejecutará de manera impredecible.

Todo lo que valoramos o creamos en una computadora se almacena en un archivo de algún formato, y todos esos archivos residen en un directorio. Los scripts pueden leer, escribir, cambiar el nombre, eliminar y mover archivos y directorios, todo lo que puede hacer en la línea de comandos.

La ventaja que tiene como ser humano es que puede ver el contenido de un directorio y saber si existe un archivo o no, o incluso si existe el directorio esperado. Si un script falla cuando manipula archivos, puede tener resultados graves y perjudiciales.

Bash proporciona un conjunto integral de pruebas que puede usar para detectar archivos y directorios, y probar muchos de sus atributos. Es fácil incorporarlos en los scripts, pero los beneficios en términos de solidez y control preciso son considerables.

RELACIONADO: Cómo usar pruebas condicionales de doble corchete en Linux

La gama de pruebas

Al combinar la declaración if con la prueba adecuada de una gran colección de pruebas de archivos y directorios, podemos determinar fácilmente si existe un archivo, si es ejecutable o escribible, y mucho más.

  • -b : Devuelve verdadero si el archivo es un archivo especial de bloque.
  • -c : Devuelve verdadero si el archivo es un carácter especial.
  • -d : Devuelve verdadero si el "archivo" es un directorio.
  • -e : Devuelve verdadero si el archivo existe.
  • -f : Devuelve verdadero si el archivo existe y es un archivo normal.
  • -g : Devuelve verdadero si el archivo tiene el conjunto de permisos setgid ( chmod g+ ).
  • -h : Devuelve verdadero si el archivo es un enlace simbólico.
  • -L : Devuelve verdadero si el archivo es un enlace simbólico.
  • -k : Devuelve verdadero si tiene establecido su sticky bit ( chmod +t ).
  • -p : Devuelve verdadero si el archivo es una canalización con nombre.
  • -r : Devuelve verdadero si el archivo es legible.
  • -s : Devuelve verdadero si los archivos existen y no están vacíos.
  • -S : Devuelve verdadero si el archivo es un socket.
  • -t : Devuelve verdadero si el descriptor de archivo se abre en una terminal.
  • -u : Devuelve verdadero si el archivo tiene el conjunto de permisos setuid ( chmod u+ ).
  • -w : Devuelve verdadero si se puede escribir en el archivo.
  • -x : Devuelve verdadero si el archivo es ejecutable.
  • -O : Devuelve verdadero si es de su propiedad.
  • -G : Devuelve verdadero si es propiedad de su grupo.
  • -N : Devuelve verdadero si el archivo ha sido modificado desde la última vez que se leyó.
  • ! : El operador lógico NOT.
  • && : El operador lógico AND.
  • || : El operador lógico OR.

La lista comienza con -b porque la prueba -a ha quedado obsoleta y reemplazada por la prueba -e .

RELACIONADO: Cómo usar SUID, SGID y Sticky Bits en Linux

Uso de las pruebas en scripts

El archivo genérico prueba if la declaración es una construcción de secuencias de comandos simple. La comparación entre corchetes dobles ” [[ ]] ” utiliza la prueba -f para determinar si existe un archivo regular con ese nombre.

Copie el texto de este script en un editor y guárdelo en un archivo llamado "script1.sh", y use chmod para hacerlo ejecutable.

 #!/bin/bash

si [[ -f $1 ]] 

después 

  echo "El archivo $1 existe." 

más 

  echo "No se puede encontrar el archivo $1". 

fi

Tienes que pasar el nombre del archivo al script en la línea de comando.

 chmod +x script1.sh 

Haciendo un script ejecutable con chmod

Deberá hacer esto con cada secuencia de comandos si desea probar los otros ejemplos del artículo.

Probemos el script en un archivo de texto sencillo.

 ./script1.sh archivo-prueba.txt 

Ejecutando script1.sh en un archivo normal

El archivo existe y el script informa correctamente ese hecho. Si eliminamos el archivo y lo intentamos de nuevo, la prueba fallará y el script nos lo informará.

 ./script1.sh archivo-prueba.txt 

Ejecutando script1.sh contra un archivo que no existe

En una situación de la vida real, su script necesitaría tomar cualquier acción apropiada. Quizás marca el error y se detiene. Tal vez crea el archivo y continúa. Puede copiar algo de un directorio de copia de seguridad para reemplazar el archivo que falta. Todo depende del propósito del guión. Pero al menos ahora el script puede tomar la decisión basándose en saber si el archivo está presente o no.

El indicador -f comprueba si el archivo está presente y si es un archivo "normal". En otras palabras, no es algo que parece ser un archivo pero no lo es, como un archivo de dispositivo.

Usaremos ls para verificar que el archivo “/dev/random” existe, y luego veremos qué hace el script con él.

 ls -lh /dev/aleatorio
 ./script/dev/aleatorio 

Ejecutar script1.sh contra un archivo de dispositivo

Debido a que nuestro script está probando archivos normales y "/dev/random" es un archivo de dispositivo, la prueba falla. Muy a menudo, para llegar al fondo de si un archivo existe, debe elegir cuidadosamente qué prueba usar, o necesita usar varias pruebas.

Este es "script2.sh", que busca archivos normales y archivos de dispositivos de caracteres.

 #!/bin/bash

si [[ -f $1 ]]
después
  echo "El archivo $1 existe."
más
  echo "Falta el archivo $1 o no es un archivo normal".
fi

si [[ -c $1 ]]
después
  echo "El archivo $1 es un archivo de dispositivo de caracteres".
más
  echo "Falta el archivo $1 o no es un archivo especial". 
fi

Si ejecutamos este script en el archivo de dispositivo "/dev/random", la primera prueba falla, lo que esperábamos, y la segunda prueba tiene éxito. Reconoce el archivo como un archivo de dispositivo.

 ./script2.sh /dev/aleatorio 

Ejecutar script2.sh contra un archivo de dispositivo de caracteres

En realidad, lo reconoce como un archivo de dispositivo de caracteres . Algunos archivos de dispositivo son archivos de dispositivo de bloque. Tal como está, nuestro guión no se las arreglará.

 ./script2.sh /dev/sda 

Ejecutando scrip2.sh contra un archivo de dispositivo de bloque

Podemos hacer uso del operador lógico OR e incluir otra prueba en la segunda declaración if. Esta vez, ya sea que el archivo sea un archivo de dispositivo de caracteres o un archivo de dispositivo de bloque, la prueba devolverá verdadero. Esto es "script3.sh".

 #!/bin/bash

si [[ -f $1 ]]
después
  echo "El archivo $1 existe."
más
  echo "Falta el archivo $1 o no es un archivo normal".
fi

si [[ -c $1 || -b $1 ]]
después
  echo "El archivo $1 es un archivo de dispositivo de bloque o carácter".
más
  echo "Falta el archivo $1 o no es un archivo especial". 
fi

Este script reconoce tanto archivos de dispositivos de caracteres como de dispositivos de bloques.

 ./script3.sh /dev/aleatorio
 ./script3.sh /dev/sda 

script3.sh maneja correctamente archivos de dispositivos de caracteres y bloques

Si es importante para usted diferenciar entre los diferentes tipos de archivos de dispositivo, puede usar sentencias if anidadas. Esto es "script4.sh".

 #!/bin/bash

si [[ -f $1 ]]
después
  echo "El archivo $1 existe."
más
  echo "Falta el archivo $1 o no es un archivo normal".
fi

si [[ -c $1 ]]
después
  echo "El archivo $1 es un archivo de dispositivo de caracteres".
más
  si [[ -b $1 ]]
  después
    echo "El archivo $1 es un archivo de dispositivo de bloque". 
  más
    echo "Falta el archivo $1 o no es un archivo de dispositivo".
  fi
fi

Este script reconoce y categoriza archivos de dispositivos de caracteres y dispositivos de bloques.

 ./script4.sh /dev/aleatorio
 ./script4.sh /dev/sda 

script8.sh identificando correctamente los archivos de dispositivos de caracteres y bloques

Usando el operador lógico AND podemos probar varias características a la vez. Este es "script5.sh". Comprueba que existe un archivo y que el script tiene permisos de lectura y escritura para él.

 #!/bin/bash

si [[ -f $1 && -r $1 && -w $1 ]]
después
  echo "El archivo $1 existe y tenemos permisos de lectura/escritura".
más
  echo "Falta el archivo $1, no es un archivo normal, o no podemos leer/escribir en él".
fi

Ejecutaremos el script en un archivo que nos pertenezca y uno que pertenezca a root .

 ./script5.sh .bashrc
 ./script5.sh /etc/fstab 

script5.sh comprobando si existe un archivo y si los permisos de lectura y escritura están configurados

Para probar la existencia de un directorio, use la prueba -d . Esto es "script6.sh". Es parte de un script de copia de seguridad. Lo primero que hace es comprobar si el directorio pasado en la línea de comandos existe o no. ¡Utiliza el operador lógico NOT ! en la prueba de sentencia if .

 #!/bin/bash

si [[ ! -d $1 ]]
después
  echo "Creando directorio de respaldo:" $1
  mkdir $1

  si [[ ! ps -eq 0 ]]
  después
    echo "No se pudo crear el directorio de respaldo:" $1
    salida
  fi
más
  echo "El directorio de copia de seguridad existe".
fi

# continuar con la copia de seguridad del archivo
echo "Copia de seguridad en: "$1

Si el directorio no existe, lo crea. Si los archivos de creación del directorio, el script finaliza. Si la creación del directorio tiene éxito o si el directorio ya existe, el script continúa con sus acciones de copia de seguridad.

Ejecutaremos el script y luego verificaremos con ls y la opción -d (directorio) si existe el directorio de respaldo.

 ./script6.sh Documentos/proyecto-copia de seguridad
 ls -d Documentos/proyecto-copia de seguridad 

script6.sh detectando si existe un directorio

Se creó el directorio de respaldo. Si ejecutamos el script nuevamente, debería informar que el directorio ya está presente.

 ./script6.sh 

script6.sh reutilizando un directorio existente

El script encuentra el directorio y continúa para realizar la copia de seguridad.

Prueba, no asumas

Tarde o temprano, las suposiciones conducirán a que sucedan cosas malas. Pruebe primero y reaccione en consecuencia.

El conocimiento es poder. Use pruebas para dar a sus scripts el conocimiento que necesitan.

RELACIONADO: Cómo permitir que los scripts de Linux detecten que se están ejecutando en máquinas virtuales