Los scripts de Bash ofrecen operadores de prueba de archivos muy útiles para examinar diversas propiedades de los archivos y directorios en sistemas tipo Unix. Estas capacidades son fundamentales para construir scripts robustos que puedan reaccionar de manera inteligente a la presencia, el tipo y los permisos de los elementos del sistema de archivos.
A continuación, se presenta un ejemplo práctico de cómo se pueden utilizar los operadores de prueba de archivos para gestionar el inicio de servicios o componentes:
#!/bin/bash
# Script para verificar y ejecutar componentes de servicio
# Define una lista de componentes a gestionar
COMPONENTES="mi_servicio_web mi_servicio_db otro_proceso_secundario"
echo "Iniciando proceso de verificación y ejecución de componentes..."
for componente_actual in $COMPONENTES
do
echo "Intentando iniciar: '$componente_actual'..."
# 1. Verificar si el componente es un archivo ejecutable en el directorio actual.
if [ -x "$componente_actual" ] && [ -f "$componente_actual" ]; then
echo " > Ejecutando '$componente_actual' desde el directorio actual."
"./$componente_actual" & # Ejecutar en segundo plano
# 2. Si no es ejecutable localmente, buscarlo en el PATH del sistema y ejecutar.
elif command -v "$componente_actual" &> /dev/null; then
echo " > Ejecutando '$componente_actual' desde el PATH del sistema."
"$componente_actual" & # Ejecutar en segundo plano
else
echo " > Error: El componente '$componente_actual' no es ejecutable ni se encuentra en el PATH."
fi
sleep 0.2 # Pequeña pausa para evitar sobrecarga y mejorar la legibilidad del log.
done
echo "Proceso de verificación de componentes completado."
Operadores de Prueba de Archivos Comunes
La siguiente tabla describe los operadores más comunes para probar las propiedades de un archivo o directorio:
| Operador | Descripción | Ejemplo |
|---|---|---|
-b archivo |
Verifica si el archivo es un dispositivo de bloque (por ejemplo, un disco duro). Devuelve verdadero si lo es. | [ -b /dev/sda ] |
-c archivo |
Verifica si el archivo es un dispositivo de carácter (por ejemplo, una terminal o un puerto serial). Devuelve verdadero si lo es. | [ -c /dev/urandom ] |
-d archivo |
Verifica si el archivo es un directorio. Devuelve verdadero si lo es. | [ -d /home/usuario/documentos ] |
-f archivo |
Verifica si el archivo es un archivo regular (no un directorio, un enlace simbólico ni un dispositivo). Devuelve verdadero si lo es. | [ -f /etc/fstab ] |
-g archivo |
Verifica si el bit SGID (Set Group ID) está configurado en el archivo. Devuelve verdadero si lo es. | [ -g /usr/bin/wall ] |
-k archivo |
Verifica si el bit adhesivo (Sticky Bit) está configurado en el archivo. Devuelve verdadero si lo es. | [ -k /tmp ] |
-p archivo |
Verifica si el archivo es una tubería con nombre (FIFO). Devuelve verdadero si lo es. | [ -p /run/systemd/private ] |
-u archivo |
Verifica si el bit SUID (Set User ID) está configurado en el archivo. Devuelve verdadero si lo es. | [ -u /bin/passwd ] |
-r archivo |
Verifica si el archivo es legible para el usuario que ejecuta el script. Devuelve verdadero si lo es. | [ -r /etc/hosts ] |
-w archivo |
Verifica si el archivo es escribible para el usuario que ejecuta el script. Devuelve verdadero si lo es. | [ -w /tmp/mi_log.txt ] |
-x archivo |
Verfiica si el archivo es ejecutable para el usuario que ejecuta el script. Devuelve verdadero si lo es. | [ -x /bin/bash ] |
-s archivo |
Verifica si el archivo no está vacío (su tamaño es mayor que cero). Devuelve verdadero si contiene datos. | [ -s /var/log/syslog ] |
-e archivo |
Verifica si el archivo o directorio existe. Devuelve verdadero si existe. | [ -e /usr/local/bin ] |
Ejemplos Avanzados de Pruebas de Archivos
Este script demuestra el uso de varios operadores de prueba de archivos con ejemplos concretos, incluyendo la creación y limpieza de archivos temporales para una ejecución segura:
#!/bin/bash
# Script de demostración exhaustiva de operadores de prueba de archivos en Bash
echo "--- Iniciando demostración de pruebas de archivos ---"
# --- Definir rutas de ejemplo para las pruebas ---
ARCHIVO_REGULAR="/tmp/ejemplo_regular_bash.txt"
ARCHIVO_VACIO="/tmp/ejemplo_vacio_bash.txt"
ARCHIVO_INEXISTENTE="/tmp/archivo_que_no_existe_xyz.txt"
DIRECTORIO_PRUEBA="/tmp/mi_directorio_bash_test"
DISPOSITIVO_CARACTER="/dev/urandom"
DISPOSITIVO_BLOQUE="/dev/sda" # Nota: puede no existir en todos los sistemas (ej. contenedores).
# Si /dev/sda no existe o causa errores, considere /dev/zero o /dev/loop0.
ARCHIVO_LEER_SISTEMA="/etc/hosts" # Un archivo de sistema típicamente legible.
ARCHIVO_ESCRIBIR_TEMPORAL="/tmp/archivo_para_escribir.log"
ARCHIVO_EJECUTAR_SISTEMA="/bin/ls" # Un ejecutable común del sistema.
# --- Preparación: Crear archivos y directorios de prueba ---
echo -e "\nPreparando archivos y directorios temporales..."
touch "$ARCHIVO_VACIO"
echo "Este es un contenido de prueba para el archivo regular." > "$ARCHIVO_REGULAR"
mkdir -p "$DIRECTORIO_PRUEBA"
touch "$ARCHIVO_ESCRIBIR_TEMPORAL"
chmod 644 "$ARCHIVO_ESCRIBIR_TEMPORAL" # Asignar permisos de escritura para el dueño.
echo -e "\n=== 1. Verificación de tipos de archivos ==="
# -f: ¿Es un archivo regular?
if [ -f "$ARCHIVO_REGULAR" ]; then
echo " [OK] '$ARCHIVO_REGULAR' es un archivo regular."
else
echo " [ERROR] '$ARCHIVO_REGULAR' NO es un archivo regular."
fi
# -d: ¿Es un directorio?
if [ -d "$DIRECTORIO_PRUEBA" ]; then
echo " [OK] '$DIRECTORIO_PRUEBA' es un directorio."
else
echo " [ERROR] '$DIRECTORIO_PRUEBA' NO es un directorio."
fi
# -b: ¿Es un dispositivo de bloque?
if [ -b "$DISPOSITIVO_BLOQUE" ]; then
echo " [OK] '$DISPOSITIVO_BLOQUE' es un dispositivo de bloque."
else
echo " [INFO] '$DISPOSITIVO_BLOQUE' NO es un dispositivo de bloque (o no está presente)."
fi
# -c: ¿Es un dispositivo de carácter?
if [ -c "$DISPOSITIVO_CARACTER" ]; then
echo " [OK] '$DISPOSITIVO_CARACTER' es un dispositivo de carácter."
else
echo " [ERROR] '$DISPOSITIVO_CARACTER' NO es un dispositivo de carácter."
fi
echo -e "\n=== 2. Verificación de existencia y contenido ==="
# -e: ¿Existe el archivo/directorio?
if [ -e "$ARCHIVO_REGULAR" ]; then
echo " [OK] '$ARCHIVO_REGULAR' EXISTE."
else
echo " [ERROR] '$ARCHIVO_REGULAR' NO EXISTE."
fi
if [ -e "$ARCHIVO_INEXISTENTE" ]; then
echo " [ERROR] '$ARCHIVO_INEXISTENTE' EXISTE (lo cual es inesperado)."
else
echo " [OK] '$ARCHIVO_INEXISTENTE' NO EXISTE (como se esperaba)."
fi
# -s: ¿El archivo no está vacío (tiene contenido)?
if [ -s "$ARCHIVO_REGULAR" ]; then
echo " [OK] '$ARCHIVO_REGULAR' NO está vacío."
else
echo " [ERROR] '$ARCHIVO_REGULAR' está vacío (lo cual es inesperado)."
fi
if [ -s "$ARCHIVO_VACIO" ]; then
echo " [ERROR] '$ARCHIVO_VACIO' NO está vacío (lo cual es inesperado)."
else
echo " [OK] '$ARCHIVO_VACIO' está vacío."
fi
echo -e "\n=== 3. Verificación de permisos (lectura, escritura, ejecución) ==="
# -r: ¿Es legible para el usuario actual?
if [ -r "$ARCHIVO_LEER_SISTEMA" ]; then
echo " [OK] '$ARCHIVO_LEER_SISTEMA' es legible."
else
echo " [ERROR] '$ARCHIVO_LEER_SISTEMA' NO es legible."
fi
# -w: ¿Es escribible para el usuario actual?
if [ -w "$ARCHIVO_ESCRIBIR_TEMPORAL" ]; then
echo " [OK] '$ARCHIVO_ESCRIBIR_TEMPORAL' es escribible."
else
echo " [ERROR] '$ARCHIVO_ESCRIBIR_TEMPORAL' NO es escribible."
fi
# -x: ¿Es ejecutable para el usuario actual?
if [ -x "$ARCHIVO_EJECUTAR_SISTEMA" ]; then
echo " [OK] '$ARCHIVO_EJECUTAR_SISTEMA' es ejecutable."
else
echo " [ERROR] '$ARCHIVO_EJECUTAR_SISTEMA' NO es ejecutable."
fi
echo -e "\n--- Demostración finalizada. Limpiando archivos temporales. ---"
rm -f "$ARCHIVO_REGULAR" "$ARCHIVO_VACIO" "$ARCHIVO_INEXISTENTE" "$ARCHIVO_ESCRIBIR_TEMPORAL"
rmdir "$DIRECTORIO_PRUEBA" 2>/dev/null # Eliminar directorio si está vacío, ignorar errores si no lo está.