Cerrábamos el Módulo 1 prometiendo que aquí empezaba «el trabajo de verdad con las herramientas», y esta es la primera. Crear, copiar, mover y eliminar ficheros es la operación más frecuente de cualquier persona que administre un sistema, y también la más peligrosa: en Linux no hay papelera de reciclaje, y un rm mal escrito no pide confirmación ni deja rastro. En esta lección aprenderás a manipular ficheros y directorios con precisión sobre srv-veloz-01, a proteger tu trabajo con copias de seguridad instantáneas y a reconocer las trampas que hacen que un comando aparentemente inofensivo destruya datos de producción.
Contenido
- Crear directorios con
mkdirymkdir -p - Crear y tocar ficheros con
touch - Copiar con
cp: las opciones que importan - Mover y renombrar con
mv - Eliminar con
rmyrmdir: el punto de no retorno - Nombres problemáticos: espacios y guiones iniciales
- Copias de seguridad rápidas antes de tocar nada
- Caso práctico: organizar
~/veloz-opsy archivar el CSV del día
- Crear directorios con
mkdir y mkdir -p
mkdir y mkdir -pmkdir (make directory) crea directorios, uno o varios por invocación. El problema aparece con estructuras anidadas:
mkdir solo crea el último elemento de la ruta y da por hecho que los padres existen. La opción -p (parents) crea todos los intermedios que falten:
mkdir: se ha creado el directorio '/home/joan/veloz-ops/logs/2026' mkdir: se ha creado el directorio '/home/joan/veloz-ops/logs/2026/08'
-v solo menciona lo que realmente ha creado: ~/veloz-ops/logs ya existía desde la lección 01-02.
-p tiene una segunda virtud, más importante todavía en scripts: no falla si el directorio ya existe. Sin -p, repetir mkdir informes devuelve error y código de salida distinto de 0; con -p, devuelve 0 en silencio. Es una operación idempotente: ejecutarla una o cien veces produce el mismo resultado. Por eso en cualquier script serio verás siempre mkdir -p. Existe además -m MODO para fijar los permisos en el momento de crear el directorio, tema que abordaremos en 02-03.
- Crear y tocar ficheros con
touch
touchtouch tiene dos usos que conviene no confundir: si el fichero no existe, lo crea vacío; si ya existe, actualiza sus fechas de acceso y modificación sin tocar el contenido.
Tamaño 0: fichero vacío, listo para editar. El segundo uso da nombre al comando y sirve para marcar hitos: muchos procesos de backup deciden qué copiar comparando fechas, y un touch vuelve a incluir el fichero. Opciones útiles: -c (no crear si no existe), -d "2026-07-01 09:00" (fijar una fecha concreta) y -r REF (copiar las fechas de otro fichero).
touch no crea ficheros con contenido. Para eso usarás un editor o, a partir de 02-04, la redirección.
- Copiar con
cp: las opciones que importan
cp: las opciones que importanLa sintaxis es cp ORIGEN DESTINO, pero el comportamiento cambia según si el destino existe y es un directorio:
cp envios.csv envios-copia.csv # destino = nombre de fichero → copia renombrada
cp envios.csv /tmp/ # destino = directorio → /tmp/envios.csv
cp a.csv b.csv c.csv /tmp/backup/ # varios orígenes → el destino DEBE ser un directorioSi el destino es un fichero que ya existe, cp lo sobrescribe sin avisar. Esta es la primera trampa seria del día.
| Opción | Nombre | Qué hace |
|---|---|---|
-r / -R |
recursive | Copia directorios con todo su contenido |
-a |
archive | Copia «tal cual»: recursivo + preserva metadatos + enlaces simbólicos |
-i |
interactive | Pregunta antes de sobrescribir |
-n |
no-clobber | Nunca sobrescribe, y no pregunta |
-v |
verbose | Muestra cada fichero copiado |
-u |
update | Copia solo si el origen es más nuevo, o el destino no existe |
Sin -r, copiar un directorio falla con cp: se omite el directorio '...'.
Qué preserva exactamente -a
-a equivale a -dR --preserve=all, y esa expansión explica su valor. Preserva:
- Modo (permisos): un script ejecutable sigue siéndolo en la copia.
- Propietario y grupo, si tienes privilegios para asignarlos.
- Marcas de tiempo: la copia conserva la fecha original, no la de hoy.
- Enlaces simbólicos: los copia como enlaces en lugar de seguirlos y duplicar datos.
Compáralo con -r a secas, que crea ficheros nuevos con la fecha actual y los permisos filtrados por tu umask (02-03). Para archivar o respaldar, -a es casi siempre lo correcto: quieres una réplica fiel, no una versión «recién hecha».
'/home/joan/veloz-ops' -> '/tmp/veloz-ops-snapshot' '/home/joan/veloz-ops/bin/informe-diario.sh' -> '/tmp/veloz-ops-snapshot/bin/informe-diario.sh'
La trampa del destino existente
Con cp, lo determinante no es la barra final del origen, sino si el destino existe: si /tmp/destino no existe, cp -a origen /tmp/destino crea la copia con ese nombre; si existe, crea /tmp/destino/origen dentro. (En rsync, que verás en 07-03, la barra final del origen sí cambia el significado; confundir ambos comportamientos es un clásico.) La forma de no equivocarse es verificar antes con ls -d /tmp/destino.
- Mover y renombrar con
mv
mvmv mueve ficheros. Y renombra ficheros. Y son exactamente la misma operación: en Unix, el nombre de un fichero no es más que una entrada en un directorio que apunta a sus datos. Mover dentro del mismo sistema de ficheros consiste en borrar esa entrada del directorio de origen y crearla en el de destino; si el directorio es el mismo y solo cambia el texto de la entrada, lo llamamos «renombrar».
mv informe.txt informe-2026-08-03.txt # renombrar
mv informe-2026-08-03.txt ~/veloz-ops/logs/ # mover
mv borrador.md ~/veloz-ops/logs/final.md # mover y renombrar a la vezConsecuencia práctica: mover dentro del mismo disco es instantáneo, aunque sean 50 GB, porque no se copian datos. Mover entre discos distintos sí implica copiar y borrar, y por eso tarda.
Igual que cp, mv sobrescribe sin preguntar. -i pregunta antes de sobrescribir; -n no sobrescribe nunca y no pregunta; -v muestra lo que hace.
En scripts, -n es preferible a -i: un script no debe quedarse esperando una respuesta que nadie va a teclear.
- Eliminar con
rm y rmdir: el punto de no retorno
rm y rmdir: el punto de no retornoLee esta sección dos veces. rm es el comando que más datos ha destruido en la historia de Unix.
rm fichero.txt # borra un fichero
rm -r directorio/ # borra un directorio y todo su contenido
rm -i *.tmp # pregunta por cada uno
rm -f fichero # fuerza: no pregunta ni protesta si no existe
rmdir directorio-vacio # borra un directorio SOLO si está vacíoNo hay papelera. rm desvincula el nombre y el espacio queda disponible para reutilizarse. La recuperación no es una operación de usuario: exige herramientas forenses, desmontar el sistema de ficheros y aun así suele fracasar. Trabaja siempre bajo el supuesto de que lo que borras se ha ido.
rmdir es el complemento seguro: como solo borra directorios vacíos, no puede destruir contenido por accidente. Úsalo cuando tu intención sea «limpiar algo que ya debería estar vacío»: si falla, es que había algo inesperado, y eso es información valiosa.
Las trampas de rutas mal escritas
rm -rf /srv/veloz/datos /historico # ← espacio de más: borra datos Y /historico
rm -rf ~/veloz-ops /logs # ← el mismo error, disfrazado
rm -rf $DIR/* # ← si DIR está vacía, esto es rm -rf /*El espacio accidental convierte un argumento en dos, y rm borra ambos sin inmutarse. El tercer caso es la razón por la que en el Módulo 3 aprenderás a entrecomillar variables y darles valores por defecto.
Hábitos que te protegen, aplicando lo aprendido en 01-05:
ls -la /srv/veloz/datos/historico/2026/07 # 1. mirar primero qué hay
echo rm -rf /srv/veloz/datos/historico/2026/07 # 2. imprimir sin ejecutar y releer
rm -rf /srv/veloz/datos/historico/2026/07 # 3. ejecutar solo si era correctoY dos reglas más en producción: nunca uses rm -rf con sudo sin haber listado antes, y prefiere mover a un directorio de cuarentena cuando la operación no sea trivialmente reversible.
- Nombres problemáticos: espacios y guiones iniciales
El shell separa los argumentos por espacios, así que informe agosto.txt se ve como dos argumentos. La solución son las comillas o el escapado:
Peor es un fichero cuyo nombre empieza por guion:
rm interpreta el nombre como opciones agrupadas. Hay dos soluciones estándar:
rm -- -fichero-raro.txt # -- marca el fin de las opciones
rm ./-fichero-raro.txt # con ./ delante ya no empieza por guionEl separador -- lo aceptan casi todos los programas GNU y significa: «lo que venga después son argumentos, no opciones». También te salvará cuando un patrón de búsqueda empiece por guion.
Sobre tildes y ñ: el sistema de ficheros los admite, pero si esos nombres acaban en una URL, en un script portable o en un sistema Windows darán guerra. Para el toolkit de Veloz Envíos adoptamos una convención estricta: minúsculas, sin tildes, guiones en vez de espacios.
- Copias de seguridad rápidas antes de tocar nada
Antes de editar un fichero de configuración en producción, hazte esta copia. Cuesta un segundo y ahorra tardes enteras:
cp -a ~/veloz-ops/etc/veloz-ops.conf ~/veloz-ops/etc/veloz-ops.conf.bak
# Si necesitas varias copias sucesivas, fecha el nombre (sustitución de comandos, 03-06)
cp -a veloz-ops.conf "veloz-ops.conf.$(date +%F).bak" # → veloz-ops.conf.2026-08-03.bak-a es deliberado: la copia conserva permisos y fecha original, así que sirve como referencia de «cómo estaba esto». Esto es una copia local: protege frente a tus propios errores de edición, no frente a un fallo de disco. El respaldo real de Veloz Envíos, con tar y rsync, llegará en 05-01 y 07-03.
- Caso práctico: organizar
~/veloz-ops y archivar el CSV del día
~/veloz-ops y archivar el CSV del día# 1. Completar la estructura del toolkit
mkdir -pv ~/veloz-ops/{bin,lib,etc,logs,tmp}
# 2. Crear el fichero de configuración y su copia de seguridad
touch ~/veloz-ops/etc/veloz-ops.conf
cp -a ~/veloz-ops/etc/veloz-ops.conf ~/veloz-ops/etc/veloz-ops.conf.bak
# 3. Preparar el archivo histórico de datos por año y mes
sudo mkdir -pv /srv/veloz/datos/historico/2026/08
# 4. Archivar una instantánea del CSV del día, conservando metadatos
sudo cp -av /srv/veloz/datos/envios.csv \
/srv/veloz/datos/historico/2026/08/envios-2026-08-03.csvLa sintaxis {bin,lib,...} es expansión de llaves y la estudiaremos en 02-05; por ahora quédate con que crea los cinco directorios de una pasada. La barra invertida final del paso 4 permite continuar el comando en la línea siguiente.
Fíjate en la decisión de diseño: copiamos, no movemos. /srv/veloz/datos/envios.csv es el fichero vivo que la API sigue escribiendo; moverlo rompería la aplicación. El histórico se alimenta de copias fechadas, y el nombre envios-2026-08-03.csv es deliberadamente ordenable alfabéticamente, que aquí equivale a ordenable cronológicamente.
La hora mostrada, 09:14, es la del fichero original, no la de la copia: eso es -a haciendo su trabajo.
Errores Comunes y Consejos
- Creer que
cpymvavisan antes de sobrescribir. No lo hacen. De forma interactiva puedes definiralias cp='cp -i'yalias mv='mv -i'en tu~/.bashrc(02-06), pero no dependas de ellos: los alias no se expanden en scripts, y acostumbrarte a la red de seguridad hace que bajes la guardia en máquinas ajenas. - Usar
-rcuando querías-a. Copiar~/veloz-opscon-rdeja los scripts con la fecha de hoy y, en algunos casos, sin el bit de ejecución. - Olvidar que
rm -rno pregunta.rm -ri directorio/pregunta paso a paso; es lento, pero en producción esa lentitud es una virtud. - Escribir la ruta con un espacio de más. Antes de cualquier borrado recursivo, pon
echodelante y lee el resultado. - Deducir el destino de
cppor la barra final. Verifica conls -dsi existe. - Llenar el disco de
.bak. Las copias rápidas son para el momento; limpia las que ya no sirven o acabarás depurando undfal 100 %.
Ejercicios
Ejercicio 1 — Montar el archivo mensual. Prepara el archivo histórico de julio de 2026 y coloca dentro una copia de los datos actuales sin tocar el fichero vivo: (1) crea /srv/veloz/datos/historico/2026/07 en un solo comando aunque falten los padres; (2) copia envios.csv allí como envios-2026-07-31.csv preservando permisos y fechas y mostrando lo que hace; (3) comprueba que el original sigue en su sitio; (4) explica por qué -a es preferible a una copia simple.
Ejercicio 2 — Limpiar un desastre de nombres. Un script mal escrito ha dejado en ~/veloz-ops/tmp los ficheros informe agosto.txt, -tmp.log y resumen.txt. Renombra el primero a informe-agosto.txt; borra -tmp.log razonando por qué rm -tmp.log falla; y mueve resumen.txt a ~/veloz-ops/logs/ sin sobrescribir nada si ya hubiera uno con ese nombre.
Ejercicio 3 — Auditar un comando peligroso. Un compañero te pasa esto para «limpiar el histórico antiguo» y te pide que lo revises antes de ejecutarlo como root:
¿Qué hace realmente? ¿Cuál era la intención? Escribe una secuencia segura que consiga la intención real.
Soluciones
Solución al Ejercicio 1
sudo mkdir -p /srv/veloz/datos/historico/2026/07
sudo cp -av /srv/veloz/datos/envios.csv \
/srv/veloz/datos/historico/2026/07/envios-2026-07-31.csv
ls -l /srv/veloz/datos/envios.csv-p es imprescindible porque faltan dos niveles intermedios. -a es preferible porque un archivo histórico debe ser una réplica fiel: si la copia recibiera la fecha de hoy perderíamos la información de cuándo se generaron los datos, que es justo lo que un histórico existe para conservar. Además conserva los permisos, evitando que una auditoría futura encuentre diferencias sin explicación.
Solución al Ejercicio 2
cd ~/veloz-ops/tmp
mv "informe agosto.txt" informe-agosto.txt
rm -- -tmp.log
mv -n resumen.txt ~/veloz-ops/logs/rm -tmp.log falla porque el shell entrega la cadena -tmp.log a rm y este la interpreta como opciones agrupadas (-t, -m, -p...). El separador -- le indica que no espere más opciones; rm ./-tmp.log funciona igual de bien. En el último paso, -n garantiza que no se pierda un resumen.txt preexistente y, a diferencia de -i, no bloquea la ejecución esperando respuesta.
Solución al Ejercicio 3
-
Qué hace realmente: el espacio antes de
/2025convierte el comando en dos argumentos. Borra recursivamente todo/srv/veloz/datos/historico—el archivo histórico completo, todos los años— e intenta además borrar el directorio/2025en la raíz. Consudoy-f, sin una sola pregunta ni mensaje de error. -
La intención era borrar el subdirectorio del año 2025:
/srv/veloz/datos/historico/2025. -
Secuencia segura:
ls -la /srv/veloz/datos/historico/2025 # 1. confirmar ruta y contenido
du -sh /srv/veloz/datos/historico/2025 # 2. ¿el volumen cuadra con lo esperado?
echo sudo rm -rf /srv/veloz/datos/historico/2025 # 3. imprimir sin ejecutar y releer
# 4. Alternativa preferible en producción: cuarentena en lugar de borrado
sudo mkdir -p /srv/veloz/cuarentena
sudo mv -n /srv/veloz/datos/historico/2025 /srv/veloz/cuarentena/La cuarentena es la mejora clave: convierte una operación irreversible en reversible. Pasadas unas semanas sin incidencias, el borrado definitivo se hace con tranquilidad. Cuando aprendas find y tar en 05-01 este flujo se automatizará, pero el criterio seguirá siendo el mismo.
Conclusión
Ya dominas la manipulación básica del sistema de ficheros: creas estructuras completas con mkdir -p, generas ficheros con touch, copias con fidelidad usando cp -a, entiendes que mover y renombrar son la misma operación y —lo más importante— has interiorizado que rm no perdona. Sabes tratar nombres con espacios y con guiones iniciales mediante comillas y --, tienes el hábito de la copia .bak antes de editar nada, y has dejado ~/veloz-ops y el archivo histórico de /srv/veloz/datos organizados para el resto del curso.
Aún manipulas los ficheros uno a uno o por nombre completo; seleccionarlos por patrones llegará en 02-05 con los comodines, y las búsquedas complejas en 05-01 con find.
En la siguiente lección, 02-02, dejamos de mover ficheros para empezar a leer lo que hay dentro. Aprenderás a explorar /var/log/veloz/app.log en vivo, a buscar errores con grep, a extraer columnas de envios.csv y a ordenar y contar resultados. Es el momento en el que los datos de Veloz Envíos empiezan a responder preguntas.
Curso de Programación en Bash
Módulo 1: Introducción a Bash
- ¿Qué es Bash?
- Configurando tu Entorno
- Navegación Básica en la Línea de Comandos
- Entendiendo el Shell
- Encontrar Ayuda: man, help y --help
Módulo 2: Comandos Básicos de Bash
- Operaciones con Archivos y Directorios
- Comandos de Procesamiento de Texto
- Permisos y Propiedad de Archivos
- Redirección y Tuberías
- Comodines y Expansión de Rutas
- Historial y Atajos de Teclado
Módulo 3: Fundamentos de Scripting
- Creando y Ejecutando un Script
- Variables y Constantes
- Operadores Básicos
- Sentencias Condicionales
- Argumentos y Entrada del Usuario
- Comillas, Expansión y Sustitución
Módulo 4: Scripting Intermedio
- Bucles en Bash
- Funciones en Bash
- Arrays y Arrays Asociativos
- Manipulación de Cadenas
- La Sentencia case y los Menús Interactivos
- Aritmética y Cálculos Numéricos
Módulo 5: Técnicas Avanzadas de Scripting
- Operaciones Avanzadas con Archivos
- Gestión de Procesos
- Manejo de Errores y Depuración
- Expresiones Regulares
- Entrada/Salida Avanzada: Descriptores y Here-Documents
- Scripts Modulares y Librerías Reutilizables
Módulo 6: Trabajando con Herramientas Externas
Módulo 7: Automatización y Programación
- Trabajos Cron
- Automatizando Tareas
- Scripts de Respaldo y Restauración
- Monitoreo y Registro
- Servicios y Temporizadores con systemd
- Automatización Remota con SSH
Módulo 8: Mejores Prácticas y Optimización
- Escribiendo Código Legible
- Optimizando Scripts en Bash
- Consideraciones de Seguridad
- Control de Versiones con Git
- Análisis Estático con ShellCheck y shfmt
- Pruebas Automatizadas con Bats
- Portabilidad: POSIX sh frente a Bashismos
