Hasta ahora todo lo que has ejecutado era inofensivo: mirar, listar, consultar. Esta lección cruza la línea. A partir de aquí los comandos escriben en el disco, y algunos de ellos borran sin preguntar y sin posibilidad de deshacer.

No es una advertencia retórica. En Linux no hay papelera de reciclaje por defecto: rm desenlaza el archivo y el espacio queda disponible para reutilizarse. Recuperar algo borrado en un sistema de archivos montado y en uso es, en la práctica, imposible. Por eso esta lección dedica un apartado entero a estrategias defensivas, y por eso el snapshot de la VM es hoy más importante que nunca.

A cambio, estas son las herramientas con las que se trabaja de verdad: crear estructuras de directorios, copiar preservando permisos, mover y renombrar, sincronizar árboles completos y empaquetar software para distribuirlo. Al terminar podrás preparar un paquete de /opt/tramontana/app listo para enviárselo a Luis, con la certeza de que llegará idéntico a como salió.

Contenido

  1. touch: crear y tocar marcas de tiempo
  2. mkdir y rmdir: estructura de directorios
  3. cp: copiar, y la trampa de la barra final
  4. mv: mover y renombrar
  5. rm: la conversación seria
  6. Renombrado por lotes con rename
  7. rsync: la forma correcta de copiar directorios
  8. tar: empaquetar
  9. Compresión: gzip, bzip2, xz y zip
  10. Práctica: preparar el paquete para Luis

  1. touch: crear y tocar marcas de tiempo

touch hace dos cosas distintas según el archivo exista o no:

  • Si no existe, lo crea vacío.
  • Si existe, actualiza sus marcas de tiempo sin tocar el contenido.
operador@srv-tramontana:~$ touch informe-agosto.txt
operador@srv-tramontana:~$ ls -l informe-agosto.txt
-rw-rw-r-- 1 operador operador 0 ago 18 10:15 informe-agosto.txt

Cero bytes: existe pero está vacío. Acepta varios argumentos:

operador@srv-tramontana:~$ touch nota1.txt nota2.txt nota3.txt

La segunda función, actualizar marcas de tiempo, es la que da nombre al comando y la que sorprende a quien solo lo conoce como «crear archivo vacío». Retomando las tres marcas de la lección anterior:

Opción Qué actualiza
(ninguna) atime y mtime al momento actual
-a Solo atime
-m Solo mtime
-t AAAAMMDDhhmm.ss Fija la marca a esa fecha concreta
-d "cadena" Fija la marca interpretando una fecha en lenguaje natural
-r fichero Copia las marcas de otro archivo
-c No crea el archivo si no existe
operador@srv-tramontana:~$ touch -t 202601011200.00 informe-agosto.txt
operador@srv-tramontana:~$ ls -l --time-style=long-iso informe-agosto.txt
-rw-rw-r-- 1 operador operador 0 2026-01-01 12:00 informe-agosto.txt

operador@srv-tramontana:~$ touch -d "yesterday 09:00" nota1.txt
operador@srv-tramontana:~$ ls -l --time-style=long-iso nota1.txt
-rw-rw-r-- 1 operador operador 0 2026-08-17 09:00 nota1.txt

Fíjate en lo que no ha cambiado:

operador@srv-tramontana:~$ stat -c 'mtime=%y%nctime=%z' informe-agosto.txt
mtime=2026-01-01 12:00:00.000000000 +0200
ctime=2026-08-18 10:18:44.331920103 +0200

El mtime dice enero, pero el ctime dice hoy. Es exactamente lo que anticipaba el ejercicio de la lección 02-03: puedes falsificar el mtime, pero el ctime delata que el inodo se tocó ahora mismo.

Usos legítimos de touch en administración:

  • Crear un archivo de bloqueo o un marcador (/var/run/tramontana.lock).
  • Forzar que una herramienta que compara fechas considere un archivo como modificado.
  • Fijar la fecha de un archivo restaurado de una copia para que coincida con el original.
  • Crear un archivo vacío antes de darle permisos restrictivos y luego escribir en él, para que nunca exista con permisos abiertos.

-c es la opción defensiva: actualiza si existe, y si no existe no hagas nada. Evita crear archivos vacíos por una errata en el nombre.

  1. mkdir y rmdir: estructura de directorios

operador@srv-tramontana:~$ mkdir informes
operador@srv-tramontana:~$ mkdir borradores publicados archivo
operador@srv-tramontana:~$ ls -F
archivo/  borradores/  datos/  informes/  publicados/  scripts/
Opción Qué hace
-p Crea los padres que falten y no falla si ya existe
-m modo Crea con esos permisos directamente
-v Informa de cada directorio creado

Sin -p, mkdir no crea rutas anidadas:

operador@srv-tramontana:~$ mkdir informes/2026/agosto
mkdir: no se puede crear el directorio «informes/2026/agosto»: No existe el fichero o el directorio

operador@srv-tramontana:~$ mkdir -p informes/2026/agosto
operador@srv-tramontana:~$ tree informes
informes
└── 2026
    └── agosto

-p tiene una segunda propiedad, tan importante como la primera: no falla si el directorio ya existe.

operador@srv-tramontana:~$ mkdir informes
mkdir: no se puede crear el directorio «informes»: El fichero ya existe
operador@srv-tramontana:~$ echo $?
1

operador@srv-tramontana:~$ mkdir -p informes
operador@srv-tramontana:~$ echo $?
0

Eso hace que mkdir -p sea idempotente: ejecutarlo diez veces deja el sistema en el mismo estado que ejecutarlo una. Es la propiedad que se busca en scripts, donde un mkdir que falla porque el directorio ya existía abortaría la ejecución sin motivo. Lo retomarás en el Módulo 4 y con Ansible en el Módulo 7.

-m crea con permisos concretos en una sola operación:

operador@srv-tramontana:~$ mkdir -m 700 privado
operador@srv-tramontana:~$ ls -ld privado
drwx------ 2 operador operador 4096 ago 18 10:24 privado

Es mejor que crear y luego hacer chmod, porque entre las dos operaciones existiría una ventana —breve, pero real— en la que el directorio tiene permisos más abiertos de lo debido. En un sistema multiusuario, esa ventana es un problema de seguridad. El significado del 700 es la lección 02-07.

Con expansión de llaves puedes crear estructuras completas de una vez:

operador@srv-tramontana:~$ mkdir -p informes/2026/{01..03}
operador@srv-tramontana:~$ tree informes/2026
informes/2026
├── 01
├── 02
├── 03
└── agosto

Esas llaves son expansión de llaves, una función del shell que se explica en la lección 03-02. Úsala ya; entenderás su mecánica más adelante.

rmdir borra un directorio, pero solo si está vacío:

operador@srv-tramontana:~$ rmdir informes
rmdir: fallo al borrar 'informes': El directorio no está vacío

operador@srv-tramontana:~$ rmdir borradores
operador@srv-tramontana:~$ ls -d borradores
ls: no se puede acceder a 'borradores': No existe el fichero o el directorio

Esa limitación no es un defecto: es una red de seguridad. rmdir no puede borrar nada por accidente porque solo actúa sobre directorios vacíos. Cuando quieras eliminar un directorio con contenido tendrás que usar rm -r, y en ese momento estás asumiendo conscientemente el riesgo.

rmdir -p elimina la rama entera mientras vaya quedando vacía:

operador@srv-tramontana:~$ rmdir -p informes/2026/agosto
operador@srv-tramontana:~$ ls -d informes
ls: no se puede acceder a 'informes': No existe el fichero o el directorio

Borró agosto, luego 2026 porque quedó vacío, y luego informes.

  1. cp: copiar, y la trampa de la barra final

operador@srv-tramontana:~$ cp datos/reservas.csv datos/reservas-copia.csv
operador@srv-tramontana:~$ ls datos/
casas.txt  reservas-copia.csv  reservas.csv

Las opciones que importan:

Opción Qué hace
-r / -R Recursivo: obligatorio para copiar directorios
-i Pregunta antes de sobrescribir
-n No sobrescribe nunca, sin preguntar
-u Copia solo si el origen es más nuevo o el destino no existe
-p Preserva modo, propietario y marcas de tiempo
-a Archivo: equivale a -dR --preserve=all. La opción para copias fieles
-v Muestra qué copia
-L / -P Sigue / no sigue los enlaces simbólicos (lección 02-06)
--backup=numbered Guarda una copia numerada del destino antes de pisarlo

cp sobrescribe sin avisar. Es el comportamiento por defecto y ha destruido mucho trabajo:

operador@srv-tramontana:~$ cp datos/casas.txt datos/reservas.csv
operador@srv-tramontana:~$ head -n 1 datos/reservas.csv
mas-figueres;Mas Figueres;Girona;6

reservas.csv ya no contiene reservas: contiene casas. No hubo ni un aviso.

Compara con la versión defensiva:

operador@srv-tramontana:~$ cp -i datos/casas.txt datos/reservas.csv
cp: ¿sobreescribir 'datos/reservas.csv'? n

Diferencia entre -p y -a:

operador@srv-tramontana:~$ ls -l --time-style=long-iso /etc/hostname
-rw-r--r-- 1 root root 16 2025-06-12 10:03 /etc/hostname

operador@srv-tramontana:~$ cp /etc/hostname /tmp/h1
operador@srv-tramontana:~$ cp -p /etc/hostname /tmp/h2
operador@srv-tramontana:~$ ls -l --time-style=long-iso /tmp/h1 /tmp/h2
-rw-r--r-- 1 operador operador 16 2026-08-18 10:31 /tmp/h1
-rw-r--r-- 1 operador operador 16 2025-06-12 10:03 /tmp/h2

La copia normal tiene la fecha de hoy; la copia con -p conserva la fecha original. El propietario cambió en ambas porque operador no puede crear archivos que pertenezcan a root (hace falta sudo; los detalles en la lección 02-07).

Qué se conserva cp cp -p cp -a
Contenido Sí Sí Sí
Permisos No (se aplica la umask) Sí Sí
Marcas de tiempo No Sí Sí
Propietario y grupo No Sí (si eres root) Sí (si eres root)
Enlaces simbólicos Los sigue y copia el contenido Los sigue Los copia como enlaces
Recursivo No No Sí
Atributos extendidos y ACL No Parcial Sí

Regla práctica: para copiar un árbol de directorios tal cual, cp -a. Para todo lo demás, cp -r basta.

La trampa de la barra final

Este es el comportamiento que más confusión genera de todo el comando. La clave: cp se comporta de forma distinta según el destino exista y sea un directorio o no.

# CASO 1: el destino NO existe -> crea un archivo con ese nombre
operador@srv-tramontana:~$ cp datos/casas.txt copia.txt
operador@srv-tramontana:~$ ls -F copia.txt
copia.txt

# CASO 2: el destino existe y ES un directorio -> copia DENTRO
operador@srv-tramontana:~$ mkdir respaldo
operador@srv-tramontana:~$ cp datos/casas.txt respaldo
operador@srv-tramontana:~$ ls respaldo/
casas.txt

En el caso 2, el archivo se llama respaldo/casas.txt. Hasta aquí es intuitivo. La sorpresa aparece con directorios:

operador@srv-tramontana:~$ tree respaldo
respaldo
└── casas.txt

# SIN barra final y con destino que YA EXISTE: copia el directorio DENTRO
operador@srv-tramontana:~$ cp -r datos respaldo
operador@srv-tramontana:~$ tree respaldo
respaldo
├── casas.txt
└── datos
    ├── casas.txt
    └── reservas.csv

# Si el destino NO existe: crea el directorio con ese nombre
operador@srv-tramontana:~$ cp -r datos respaldo2
operador@srv-tramontana:~$ tree respaldo2
respaldo2
├── casas.txt
└── reservas.csv

El mismo comando produce dos resultados distintos según si respaldo existía. Ese es el fallo clásico: ejecutas un script de copia dos veces y la segunda te crea respaldo/datos/ anidado dentro.

Y ahora la barra final en el origen, que en cp no cambia nada pero en rsync lo cambia todo:

operador@srv-tramontana:~$ cp -r datos/ respaldo3
operador@srv-tramontana:~$ tree respaldo3
respaldo3
├── casas.txt
└── reservas.csv

Con cp, datos y datos/ dan el mismo resultado. En rsync no, como verás en el apartado 7. Es una de las incoherencias históricas de Unix con las que hay que convivir.

Defensa práctica: cuando copies directorios, ejecuta antes ls -d destino para saber si existe. Y en scripts, usa siempre destinos explícitos y comprobados.

  1. mv: mover y renombrar

mv hace las dos cosas con el mismo comando, porque en el fondo son la misma operación: cambiar la entrada de directorio que apunta a un archivo.

# Renombrar
operador@srv-tramontana:~$ mv informe-agosto.txt informe-2026-08.txt

# Mover
operador@srv-tramontana:~$ mv informe-2026-08.txt respaldo/

# Mover y renombrar a la vez
operador@srv-tramontana:~$ mv respaldo/informe-2026-08.txt datos/informe-mensual.txt
Opción Qué hace
-i Pregunta antes de sobrescribir
-n No sobrescribe nunca
-u Mueve solo si el origen es más nuevo
-v Informa de cada movimiento
-b Hace copia de seguridad del destino antes de pisarlo
-t dir Indica el destino primero, útil en scripts

Como cp, mv sobrescribe sin preguntar, y con una diferencia crucial: en cp pierdes solo el destino; en mv pierdes el destino y el origen deja de estar donde estaba.

Dentro y fuera del sistema de archivos

Este detalle explica un comportamiento que desconcierta cuando mueves archivos grandes.

operador@srv-tramontana:~$ ls -i datos/casas.txt
262149 datos/casas.txt
operador@srv-tramontana:~$ mv datos/casas.txt respaldo/casas.txt
operador@srv-tramontana:~$ ls -i respaldo/casas.txt
262149 respaldo/casas.txt

El mismo inodo. No se ha copiado ni un byte: solo se ha borrado una entrada de directorio y se ha creado otra apuntando al mismo inodo. Por eso mover un archivo de 40 GB dentro del mismo disco es instantáneo.

Ahora, entre sistemas de archivos distintos:

flowchart TD
    A["mv origen destino"] --> B{"¿Mismo sistema<br/>de archivos?"}
    B -->|Sí| C["rename(): cambia la entrada<br/>de directorio"]
    C --> D["INSTANTÁNEO<br/>Mismo inodo<br/>Conserva todo"]
    B -->|No| E["Copiar bytes al destino"]
    E --> F["Borrar el origen"]
    F --> G["LENTO: depende del tamaño<br/>Inodo nuevo<br/>Interrumpible a medias"]

Consecuencias prácticas de la rama derecha:

  • Tarda: mover 40 GB de / a un disco USB implica leer y escribir 40 GB.
  • Necesita espacio libre en el destino durante toda la operación.
  • Si se interrumpe a mitad (corte de luz, Ctrl+C), el destino queda con un archivo parcial y el origen puede haberse borrado parcialmente si eran varios archivos. mv no es atómico entre sistemas de archivos.
  • El ctime cambia y el propietario puede cambiar, porque en realidad se ha creado un archivo nuevo.

Cómo saber si dos rutas están en el mismo sistema de archivos:

operador@srv-tramontana:~$ df /home/operador /opt/tramontana
S.ficheros     bloques de 1K  Usados Disponibles Uso% Montado en
/dev/sda2           23791616 6984924    15574056  31% /
/dev/sda2           23791616 6984924    15574056  31% /

Mismo dispositivo, /dev/sda2: el movimiento será instantáneo. Si aparecieran dispositivos distintos, sería copiar y borrar.

Regla para mover cosas grandes entre discos: usa rsync y borra después, tras verificar. Así, si algo falla, el origen sigue intacto.

  1. rm: la conversación seria

rm elimina archivos. En un sistema de archivos montado y en uso, lo hace de forma irreversible.

operador@srv-tramontana:~$ rm copia.txt
operador@srv-tramontana:~$ rm nota1.txt nota2.txt nota3.txt
Opción Qué hace
-r / -R Recursivo: obligatorio para directorios
-f Fuerza: no pregunta, ignora los archivos que no existen
-i Pregunta por cada archivo
-I Pregunta una sola vez si hay más de 3 archivos o es recursivo
-v Muestra qué borra
-d Borra directorios vacíos, como rmdir
--one-file-system No cruza a otros sistemas de archivos al recorrer
--preserve-root Rechaza operar sobre / (activo por defecto)
operador@srv-tramontana:~$ rm -rI respaldo3
rm: ¿eliminar 1 argumento recursivamente? s

-I es el punto dulce: te para a pensar una vez, sin la fatiga de -i preguntando cuatrocientas veces (que acaba haciendo que respondas «sí» automáticamente, que es peor que no preguntar).

Por qué rm -rf merece un apartado propio

rm -rf es la combinación que borra un árbol completo sin una sola pregunta y sin quejarse de nada. Es necesaria en scripts y es la responsable de la mayoría de los desastres de datos autoinfligidos.

El caso paradigmático es el de la variable vacía. Un script contiene:

rm -rf "$DESTINO/$SUBDIR"

Si por cualquier motivo DESTINO y SUBDIR están vacías —porque un cd previo falló, porque un fichero de configuración no se leyó, porque hubo una errata en el nombre de la variable— la línea que se ejecuta es:

rm -rf "/"

Este error ha ocurrido en empresas reales y ha llegado a borrar sistemas enteros en producción. El caso más conocido públicamente es el de un instalador de un juego comercial que, por esta misma causa, borraba el directorio personal completo de sus usuarios.

Las versiones modernas de rm incluyen --preserve-root, que rechaza rm -rf /:

operador@srv-tramontana:~$ sudo rm -rf /
rm: es peligroso operar recursivamente en '/'
rm: use --no-preserve-root para saltar esta medida de seguridad

Pero esa protección solo cubre la raíz exacta. rm -rf /home o rm -rf /opt/tramontana se ejecutan sin objeción. Y con la barra: rm -rf "$DESTINO"/ cuando DESTINO está vacía da rm -rf /, protegido; pero rm -rf "$DESTINO"/* con DESTINO vacía da rm -rf /*, que no está protegido y borra todo el contenido de la raíz.

Estrategias defensivas

1. Mirar antes de borrar. El hábito que ya conoces, ahora obligatorio:

operador@srv-tramontana:~$ ls -la /srv/tramontana/backups/temporales/
operador@srv-tramontana:~$ rm -rI /srv/tramontana/backups/temporales/

Y con patrones, más aún: ejecuta el ls con el mismo patrón, comprueba la lista y solo entonces cambia ls por rm con la flecha arriba.

2. Usar -I por costumbre en trabajo interactivo.

3. Papelera con trash-cli. Existe un equivalente a la papelera de escritorio para la terminal:

operador@srv-tramontana:~$ sudo apt install -y trash-cli
operador@srv-tramontana:~$ trash-put datos/informe-mensual.txt
operador@srv-tramontana:~$ trash-list
2026-08-18 10:52:31 /home/operador/datos/informe-mensual.txt
operador@srv-tramontana:~$ trash-restore

Es útil en tu portátil. En un servidor tiene un inconveniente serio: los archivos siguen ocupando espacio en ~/.local/share/Trash, y si borrabas para liberar disco, no has liberado nada. Úsalo con criterio.

4. Alias defensivos. Se puede hacer que rm sea rm -I por defecto mediante un alias. Los aliases se estudian en la lección 03-01, y allí discutiremos por qué esta práctica concreta es discutible: te acostumbras a una protección que no existe en los demás servidores, y el día que trabajes en una máquina ajena tendrás una falsa sensación de seguridad.

5. Comillas y --. Entrecomilla siempre las variables y usa -- antes de nombres que vengan de fuera.

6. Lo que de verdad te salva: copias de seguridad. Ninguna de las medidas anteriores protege contra un borrado deliberado y bien escrito. Lo único que protege es tener copias en otro sitio, y eso es la lección 05-08. Y en tu laboratorio, el snapshot de la VM.

Una última nota técnica: rm no borra el contenido, solo desenlaza el nombre. Los datos siguen en los bloques hasta que se sobrescriben. Eso significa dos cosas opuestas: que un forense podría recuperarlos, y que tú, en la práctica, no vas a poder porque el sistema seguirá escribiendo encima mientras lo intentas. Para borrado seguro real existe shred, con sus propias limitaciones en discos SSD y sistemas con journal.

  1. Renombrado por lotes con rename

Renombrar cincuenta archivos a mano no es opción. rename (la versión Perl, que es la de Debian y Ubuntu) aplica una transformación a muchos nombres:

operador@srv-tramontana:~$ ls informes/
informe_enero.TXT  informe_febrero.TXT  informe_marzo.TXT

operador@srv-tramontana:~$ rename -n 's/\.TXT$/.txt/' informes/*.TXT
rename(informes/informe_enero.TXT, informes/informe_enero.txt)
rename(informes/informe_febrero.TXT, informes/informe_febrero.txt)
rename(informes/informe_marzo.TXT, informes/informe_marzo.txt)

operador@srv-tramontana:~$ rename 's/\.TXT$/.txt/' informes/*.TXT
operador@srv-tramontana:~$ ls informes/
informe_enero.txt  informe_febrero.txt  informe_marzo.txt

-n (o --nono) es obligatorio en la primera ejecución: muestra lo que haría sin hacerlo. Es el equivalente al «mirar antes de actuar» para renombrados masivos.

Más ejemplos:

# Sustituir guiones bajos por guiones
operador@srv-tramontana:~$ rename -n 's/_/-/g' informes/*
rename(informes/informe_enero.txt, informes/informe-enero.txt)

# Añadir un prefijo
operador@srv-tramontana:~$ rename -n 's/^/2026-/' informes/*
rename(informes/informe-enero.txt, informes/2026-informe-enero.txt)

# Pasar a minúsculas
operador@srv-tramontana:~$ rename -n 'y/A-Z/a-z/' informes/*

La sintaxis s/patrón/reemplazo/ son expresiones regulares de Perl, tema de la lección 03-02. De momento te basta con el patrón literal y -n para verificar.

Cuidado con dos cosas: en algunas distribuciones (Fedora, RHEL) rename es un programa completamente distinto con otra sintaxis, y rename sobrescribe sin avisar si el nombre destino ya existe. Añade -v para ver qué hace realmente.

  1. rsync: la forma correcta de copiar directorios

rsync está diseñado para sincronizar árboles de directorios. Frente a cp -a tiene tres ventajas que lo hacen la herramienta por defecto en cuanto la copia es grande o importante:

cp -a rsync -av
Copia incremental No: copia todo cada vez Sí: solo lo que cambió
Reanudable No: hay que empezar de cero Sí (con --partial)
Progreso Silencioso --progress
Verificación Ninguna Suma de comprobación del contenido
Borrar lo sobrante en destino No --delete
Exclusiones No --exclude
Copia remota por SSH No Sí, nativa
operador@srv-tramontana:~$ rsync -av /opt/tramontana/app/ /srv/tramontana/backups/app-copia/
sending incremental file list
created directory /srv/tramontana/backups/app-copia
./
ejecutable
version.txt
plantillas/
plantillas/confirmacion.html
plantillas/factura.html

sent 50.331.208 bytes  received 115 bytes  100.662.646,00 bytes/sec
total size is 50.329.412  speedup is 1,00

Segunda ejecución, sin cambios:

operador@srv-tramontana:~$ rsync -av /opt/tramontana/app/ /srv/tramontana/backups/app-copia/
sending incremental file list

sent 143 bytes  received 19 bytes  324,00 bytes/sec
total size is 50.329.412  speedup is 310.675,38

162 bytes en vez de 50 MB. Ha comparado y no ha encontrado nada que copiar. Ese es el ahorro que justifica usar rsync para cualquier cosa que se repita.

Opciones esenciales:

Opción Qué hace
-a Modo archivo: recursivo + preserva permisos, fechas, propietarios y enlaces
-v Detallado
-h Cifras legibles
--progress Barra de progreso por archivo
-n / --dry-run Simula sin copiar nada
--delete Borra en el destino lo que ya no está en el origen
--exclude 'patrón' Excluye rutas
-c Compara por suma de comprobación en vez de por tamaño y fecha
-z Comprime durante la transferencia (útil solo en red)

La barra final en rsync sí importa

Aquí sí, y es el error número uno con esta herramienta:

# CON barra en el origen: copia el CONTENIDO de app
operador@srv-tramontana:~$ rsync -av /opt/tramontana/app/ /tmp/destino/
# Resultado: /tmp/destino/ejecutable, /tmp/destino/version.txt...

# SIN barra: copia el DIRECTORIO app dentro del destino
operador@srv-tramontana:~$ rsync -av /opt/tramontana/app /tmp/destino/
# Resultado: /tmp/destino/app/ejecutable, /tmp/destino/app/version.txt...

Mnemotecnia: la barra final significa «el contenido de». Sin barra, «la carpeta misma».

--delete combinado con esto es peligroso, porque borra en el destino todo lo que no esté en el origen. Si te equivocas de nivel, vacías el destino. Siempre -n primero:

operador@srv-tramontana:~$ rsync -avn --delete /opt/tramontana/app/ /srv/tramontana/backups/app-copia/
sending incremental file list
deleting obsoleto.txt

sent 156 bytes  received 22 bytes  356,00 bytes/sec

-n te ha enseñado que iba a borrar obsoleto.txt. Ahora decides con información.

El uso de rsync para copias de seguridad reales —con rotación, copias incrementales enlazadas y destinos remotos— es la lección 05-08. Aquí lo usas como el cp bueno para directorios.

  1. tar: empaquetar

tar (tape archive) junta muchos archivos en uno solo conservando la estructura, los permisos y las fechas. Por sí mismo no comprime: eso lo hace un compresor externo al que llama.

Los tres modos de operación son excluyentes, como averiguaste leyendo el manual en la lección 02-02:

Opción Modo
-c Create: crear
-x eXtract: extraer
-t lisT: listar el contenido

Y las opciones que acompañan:

Opción Qué hace
-f fichero Nombre del archivo. Debe ir la última si agrupas opciones
-v Detallado
-z Comprimir con gzip (.tar.gz)
-j Comprimir con bzip2 (.tar.bz2)
-J Comprimir con xz (.tar.xz)
-C dir Cambia a ese directorio antes de operar
--exclude='patrón' Excluye rutas
-p Preserva permisos al extraer

Crear:

operador@srv-tramontana:~$ tar -czvf /tmp/app-3.2.1.tar.gz -C /opt/tramontana app
app/
app/ejecutable
app/version.txt
app/plantillas/
app/plantillas/confirmacion.html
app/plantillas/factura.html

Desglose de la orden, que es lo importante:

  • -c crear, -z comprimir con gzip, -v mostrar, -f seguido del nombre del archivo resultante.
  • -C /opt/tramontana hace que tar se sitúe ahí antes de empaquetar. Sin esto, empaquetaría opt/tramontana/app/... con toda la jerarquía dentro.
  • app es lo que se empaqueta, ya relativo a -C.

Listar antes de extraer es obligatorio:

operador@srv-tramontana:~$ tar -tzvf /tmp/app-3.2.1.tar.gz
drwxr-xr-x root/root         0 2026-08-18 08:30 app/
-rwxr-xr-x root/root  50319872 2026-08-18 08:30 app/ejecutable
-rw-r--r-- root/root        26 2026-08-18 08:30 app/version.txt
drwxr-xr-x root/root         0 2026-08-18 08:30 app/plantillas/
-rw-r--r-- root/root      4218 2026-08-18 08:30 app/plantillas/confirmacion.html
-rw-r--r-- root/root      2104 2026-08-18 08:30 app/plantillas/factura.html

Por qué es obligatorio: para comprobar que el archivo tiene un directorio raíz único. Si en lugar de app/... vieras los ficheros sueltos en la raíz del paquete, al extraerlo te esparciría decenas de archivos por tu directorio actual. Es lo que se conoce como tarbomb, y limpiarlo a mano es tedioso.

Extraer:

operador@srv-tramontana:~$ mkdir -p /tmp/prueba && tar -xzvf /tmp/app-3.2.1.tar.gz -C /tmp/prueba
operador@srv-tramontana:~$ tree /tmp/prueba
/tmp/prueba
└── app
    ├── ejecutable
    ├── plantillas
    │   ├── confirmacion.html
    │   └── factura.html
    └── version.txt

Extraer siempre con -C a un directorio vacío evita el problema del tarbomb por completo.

Las versiones modernas de tar detectan la compresión automáticamente al extraer, así que -z, -j o -J no son necesarios para descomprimir. Sí lo son al crear, porque ahí tar no puede adivinar qué quieres.

Excluir lo que no debe viajar:

operador@srv-tramontana:~$ tar -czf /tmp/app-limpio.tar.gz \
    --exclude='*.log' --exclude='*.tmp' --exclude='cache' \
    -C /opt/tramontana app

Y una nota que vale oro: la sintaxis histórica de tar admite las opciones sin guion (tar czf) porque es anterior a la convención de guiones de POSIX. Ambas funcionan. Usa la de guiones, que es la que se entiende.

  1. Compresión: gzip, bzip2, xz y zip

Los compresores de Unix trabajan sobre un solo archivo y por defecto sustituyen el original:

operador@srv-tramontana:~$ ls -lh /tmp/datos.csv
-rw-rw-r-- 1 operador operador 12M ago 18 11:02 /tmp/datos.csv

operador@srv-tramontana:~$ gzip /tmp/datos.csv
operador@srv-tramontana:~$ ls -lh /tmp/datos.csv*
-rw-rw-r-- 1 operador operador 2,1M ago 18 11:02 /tmp/datos.csv.gz

datos.csv ya no existe: se ha convertido en datos.csv.gz. Para conservar el original hay que pedirlo con -k:

operador@srv-tramontana:~$ gzip -k /tmp/datos.csv
operador@srv-tramontana:~$ gunzip /tmp/datos.csv.gz     # o gzip -d

Comparativa sobre un archivo de texto de 100 MB, que es donde estas diferencias se notan:

Compresor Extensión Ratio típico Velocidad al comprimir Al descomprimir Uso de RAM Cuándo usarlo
gzip .gz ~30 % Muy rápida Muy rápida Baja Por defecto. Logs, transferencias, todo lo cotidiano
bzip2 .bz2 ~25 % Lenta Lenta Media Poco recomendable hoy: xz lo supera
xz .xz ~20 % Muy lenta Rápida Alta Distribuir software, archivar a largo plazo
zstd .zst ~28 % Muy rápida Muy rápida Media La alternativa moderna a gzip
zip .zip ~32 % Rápida Rápida Baja Compatibilidad con Windows

La regla de decisión:

  • Comprimes muchas veces y descomprimes pocas (logs rotados a diario): gzip. La velocidad importa más que el tamaño.
  • Comprimes una vez y descomprimes muchas (una release que se descargará mil veces): xz. El tiempo de compresión se paga una sola vez y ahorras ancho de banda en cada descarga.
  • Se lo pasas a alguien con Windows: zip.

zip es el único que archiva y comprime a la vez, como en Windows:

operador@srv-tramontana:~$ zip -r /tmp/app.zip /opt/tramontana/app
  adding: opt/tramontana/app/ (stored 0%)
  adding: opt/tramontana/app/ejecutable (deflated 62%)
  ...

operador@srv-tramontana:~$ unzip -l /tmp/app.zip
operador@srv-tramontana:~$ unzip /tmp/app.zip -d /tmp/desde-zip

Su gran limitación en Linux: no preserva bien los permisos ni la propiedad de Unix. Si empaquetas con zip y desempaquetas, los bits de ejecución pueden perderse y el script deja de funcionar. Por eso en Linux se usa tar, que sí los conserva, y zip solo cuando el destinatario usa Windows.

Herramientas para trabajar con archivos comprimidos sin descomprimirlos, muy útiles con logs:

operador@srv-tramontana:~$ zcat /var/log/tramontana/acceso.log.1.gz
operador@srv-tramontana:~$ zless /var/log/tramontana/acceso.log.1.gz
operador@srv-tramontana:~$ zgrep "ERROR" /var/log/tramontana/errores.log.2.gz

  1. Práctica: preparar el paquete para Luis

Luis Ferrer necesita una copia exacta de la versión 3.2.1 desplegada en producción para reproducir un fallo en su portátil. Marta ha aprobado enviársela. El paquete no debe incluir logs ni ficheros temporales, y tiene que llegar íntegro.

Paso 1: verificar qué vas a empaquetar.

operador@srv-tramontana:~$ cat /opt/tramontana/app/version.txt
Tramontana Reservas 3.2.1
operador@srv-tramontana:~$ du -sh /opt/tramontana/app
48M	/opt/tramontana/app
operador@srv-tramontana:~$ tree -L 2 /opt/tramontana/app
/opt/tramontana/app
├── ejecutable
├── plantillas
│   ├── confirmacion.html
│   └── factura.html
└── version.txt

Paso 2: crear el directorio de trabajo. No se empaqueta en /tmp a secas: se usa un sitio con espacio y donde el archivo no desaparezca en el próximo reinicio.

operador@srv-tramontana:~$ mkdir -p /srv/tramontana/backups/envios

Paso 3: empaquetar, excluyendo lo que no debe salir.

operador@srv-tramontana:~$ sudo tar -czvf /srv/tramontana/backups/envios/tramontana-app-3.2.1.tar.gz \
    --exclude='*.log' --exclude='*.tmp' --exclude='__pycache__' \
    -C /opt/tramontana app
app/
app/ejecutable
app/version.txt
app/plantillas/
app/plantillas/confirmacion.html
app/plantillas/factura.html

Paso 4: verificar el resultado. Nunca envíes un paquete que no has listado.

operador@srv-tramontana:~$ ls -lh /srv/tramontana/backups/envios/
total 19M
-rw-r--r-- 1 root root 19M ago 18 11:20 tramontana-app-3.2.1.tar.gz

operador@srv-tramontana:~$ tar -tzvf /srv/tramontana/backups/envios/tramontana-app-3.2.1.tar.gz
drwxr-xr-x root/root         0 2026-08-18 08:30 app/
-rwxr-xr-x root/root  50319872 2026-08-18 08:30 app/ejecutable
-rw-r--r-- root/root        26 2026-08-18 08:30 app/version.txt
drwxr-xr-x root/root         0 2026-08-18 08:30 app/plantillas/
-rw-r--r-- root/root      4218 2026-08-18 08:30 app/plantillas/confirmacion.html
-rw-r--r-- root/root      2104 2026-08-18 08:30 app/plantillas/factura.html

48 MB comprimidos a 19 MB, un solo directorio raíz app/, permisos preservados (fíjate en el -rwxr-xr-x del ejecutable) y ningún .log dentro.

Paso 5: generar una suma de comprobación para que Luis pueda verificar que el archivo ha llegado íntegro. Es el mismo mecanismo que usaste al verificar la ISO de Ubuntu en la lección 01-04.

operador@srv-tramontana:~$ cd /srv/tramontana/backups/envios
operador@srv-tramontana:/srv/tramontana/backups/envios$ sha256sum tramontana-app-3.2.1.tar.gz | sudo tee tramontana-app-3.2.1.tar.gz.sha256
9f2c4a1e8b3d7f60a5c2e1b4d8f3a70c9e2b5d1f8a4c7e0b3d6f9a2c5e8b1d4f  tramontana-app-3.2.1.tar.gz

Luis, al recibirlo, ejecuta:

luis@portatil-luis:~$ sha256sum -c tramontana-app-3.2.1.tar.gz.sha256
tramontana-app-3.2.1.tar.gz: La suma coincide

Paso 6: prueba de extracción en local. Comprobar que el paquete se abre bien antes de enviarlo, no después de que Luis diga que no funciona.

operador@srv-tramontana:~$ mkdir -p /tmp/verificacion
operador@srv-tramontana:~$ tar -xzf /srv/tramontana/backups/envios/tramontana-app-3.2.1.tar.gz -C /tmp/verificacion
operador@srv-tramontana:~$ diff -rq /opt/tramontana/app /tmp/verificacion/app
operador@srv-tramontana:~$ echo $?
0

diff -rq compara dos árboles recursivamente e informa solo de las diferencias. Sin salida y con código 0: son idénticos. Verás diff en detalle en la lección siguiente.

Paso 7: limpiar.

operador@srv-tramontana:~$ rm -rI /tmp/verificacion
rm: ¿eliminar 1 argumento recursivamente? s

Procedimiento completo, reproducible y verificado. La transferencia del archivo a Luis se hará con scp o rsync sobre SSH, que es la lección 06-02.

Errores Comunes y Consejos

Olvidar -r al copiar o borrar directorios. cp: se omite el directorio y rm: no se puede borrar: es un directorio son el mismo aviso.

La barra final. En cp casi no importa; en rsync decide si copias la carpeta o su contenido. Y en cp -r, el resultado depende de si el destino ya existía.

cp y mv sobrescriben en silencio. No hay confirmación por defecto. -i o -n cuando el destino pueda existir.

Copiar configuración con cp en vez de cp -p. Pierdes las fechas, que muchas veces son la única pista de cuándo se cambió algo.

Empaquetar con rutas absolutas. tar -czf x.tar.gz /opt/tramontana/app guarda la jerarquía opt/tramontana/app/ dentro. Usa -C y rutas relativas.

Extraer sin listar primero. tar -tzvf antes de tar -xzf, siempre.

zip para archivos de Linux. Pierde bits de ejecución y propiedad. tar para Linux, zip solo para Windows.

Consejo: rsync -n y rename -n antes de la versión real. El modo simulación es gratis y te enseña exactamente lo que va a pasar.

Consejo: nombra los paquetes con versión y fecha. tramontana-app-3.2.1.tar.gz es informativo; backup.tar.gz no dice nada dentro de tres meses.

Consejo: acompaña siempre un paquete de su sha256sum. Cuesta un comando y elimina toda una categoría de incidencias.

Consejo: antes de un rm -r, pulsa Ctrl+A y escribe ls -la delante. Miras, y luego flecha arriba y lo cambias por el rm. Diez segundos que han salvado muchos datos.

Ejercicios

Ejercicio 1: montar una estructura de trabajo

En tu home de srv-tramontana, con el mínimo número de comandos:

  1. Crea la estructura trabajo/2026/{07,08,09}/informes y trabajo/2026/{07,08,09}/datos.
  2. Crea un archivo trabajo/2026/08/informes/resumen.txt con fecha de modificación del 1 de agosto de 2026 a las 09:00.
  3. Copia ~/datos/reservas.csv a trabajo/2026/08/datos/ preservando sus marcas de tiempo, y verifícalo.
  4. Renombra todos los .txt de trabajo/2026/08/informes/ a .md sin equivocarte (usa el modo simulación).

Ejercicio 2: revisar el comando de Luis

Luis te propone este procedimiento para hacer una copia diaria de la aplicación antes de cada despliegue:

cp -r /opt/tramontana/app /srv/tramontana/backups/app-backup
tar czf /srv/tramontana/backups/app.tar.gz /opt/tramontana/app

Encuentra al menos cinco problemas y reescribe el procedimiento correctamente.

Ejercicio 3: paquete de datos para Marta

Marta necesita llevarse a una reunión los datos de reservas y el listado de casas. Trabaja con Windows y quiere abrir los archivos con Excel. Además pide que el paquete incluya un pequeño informe de qué contiene.

Prepara el envío completo: crea el informe, empaqueta en el formato adecuado, verifica el contenido del paquete y genera la suma de comprobación. Justifica la elección del formato de compresión.

Soluciones

Solución 1

operador@srv-tramontana:~$ mkdir -p trabajo/2026/{07,08,09}/{informes,datos}
operador@srv-tramontana:~$ tree trabajo
trabajo
└── 2026
    ├── 07
    │   ├── datos
    │   └── informes
    ├── 08
    │   ├── datos
    │   └── informes
    └── 09
        ├── datos
        └── informes

Un solo comando. La expansión de llaves anidada genera las seis combinaciones y -p crea todos los padres. Sin -p fallaría porque trabajo y trabajo/2026 no existen.

operador@srv-tramontana:~$ touch -t 202608010900.00 trabajo/2026/08/informes/resumen.txt
operador@srv-tramontana:~$ ls -l --time-style=long-iso trabajo/2026/08/informes/
total 0
-rw-rw-r-- 1 operador operador 0 2026-08-01 09:00 resumen.txt

touch con -t crea y fija la marca en una sola operación. El formato es AAAAMMDDhhmm.ss.

operador@srv-tramontana:~$ stat -c '%n %y' datos/reservas.csv
datos/reservas.csv 2026-08-18 07:55:02.882910233 +0200

operador@srv-tramontana:~$ cp -p datos/reservas.csv trabajo/2026/08/datos/

operador@srv-tramontana:~$ stat -c '%n %y' trabajo/2026/08/datos/reservas.csv
trabajo/2026/08/datos/reservas.csv 2026-08-18 07:55:02.882910233 +0200

Las marcas coinciden al nanosegundo. Sin -p, la copia tendría la fecha de ahora. Fíjate en que el destino termina en /: como el directorio existe, la copia se hace dentro conservando el nombre.

operador@srv-tramontana:~$ rename -n 's/\.txt$/.md/' trabajo/2026/08/informes/*.txt
rename(trabajo/2026/08/informes/resumen.txt, trabajo/2026/08/informes/resumen.md)

operador@srv-tramontana:~$ rename 's/\.txt$/.md/' trabajo/2026/08/informes/*.txt
operador@srv-tramontana:~$ ls trabajo/2026/08/informes/
resumen.md

El \. escapa el punto para que signifique un punto literal y no «cualquier carácter», y el $ ancla el patrón al final del nombre, de modo que un archivo llamado notas.txt.viejo no se vería afectado. Ambas cosas son expresiones regulares (lección 03-02).

Solución 2

Los problemas del procedimiento de Luis:

1. Ambos comandos sobrescriben el respaldo anterior sin avisar. El nombre app-backup y app.tar.gz son fijos. Cada día se pisa la copia del día anterior, así que en realidad solo existe una copia: la de ayer. Si el problema se detecta dos días después, no hay a qué volver.

2. Peor aún: se sobrescribe antes de saber si el despliegue va bien. Si el despliegue de hoy falla y ya has machacado la copia buena con la copia de la versión rota, has perdido el punto de retorno.

3. cp -r no preserva permisos ni propietarios. El ejecutable puede perder su bit de ejecución y todo pasa a pertenecer al usuario que ejecuta el comando. Restaurar esa copia dejaría la aplicación sin arrancar. Debe ser cp -a o, mejor, rsync -a.

4. tar czf con ruta absoluta. Guarda la jerarquía opt/tramontana/app/ dentro del paquete. Al extraer no obtienes app/, sino tres niveles de directorios, y tar avisa con «eliminando la / inicial de los nombres». Falta -C.

5. Se hacen dos copias redundantes de lo mismo, una sin comprimir (48 MB) y otra comprimida (19 MB), ocupando 67 MB por despliegue sin que ninguna aporte nada que la otra no tenga.

6. No hay verificación. Nadie comprueba que el .tar.gz se pueda abrir ni que contenga lo que debe. Una copia que no se ha verificado no es una copia: es una suposición.

7. No hay ningún control de espacio. Si /srv se llena a mitad del tar, queda un archivo truncado que parece una copia válida.

Procedimiento reescrito:

#!/bin/bash
# Copia previa al despliegue de Tramontana Reservas
# Uso: ejecutar ANTES de desplegar

FECHA=$(date +%F-%H%M)
VERSION=$(cat /opt/tramontana/app/version.txt | tr ' ' '-')
DESTINO=/srv/tramontana/backups/pre-despliegue
PAQUETE="$DESTINO/app-${FECHA}.tar.gz"

# 1. Asegurar el destino (idempotente)
mkdir -p "$DESTINO" || exit 1

# 2. Comprobar que hay espacio suficiente
df -h "$DESTINO"

# 3. Empaquetar con nombre único por fecha, preservando permisos
tar -czf "$PAQUETE" -C /opt/tramontana app || exit 1

# 4. Verificar que el paquete se puede leer y qué contiene
tar -tzf "$PAQUETE" > /dev/null || exit 1
echo "Contenido:"
tar -tzvf "$PAQUETE"

# 5. Suma de comprobación
sha256sum "$PAQUETE" > "$PAQUETE.sha256"

echo "Copia creada: $PAQUETE"

Correcciones aplicadas:

  • Nombre con fecha y hora: cada ejecución crea un archivo distinto. Nunca se pisa nada.
  • Un solo paquete comprimido en vez de dos copias.
  • -C /opt/tramontana app: dentro del paquete hay un único app/ limpio.
  • tar preserva permisos y propietarios por diseño, así que no hace falta -a.
  • || exit 1 en cada paso crítico: si algo falla, el script para en vez de continuar como si nada. Es el &&/|| de la lección 02-01 aplicado.
  • Verificación con tar -tzf antes de dar la copia por buena.
  • Suma de comprobación para detectar corrupción posterior.

Lo que aún le falta y llegará en su momento: rotación (borrar copias de más de N días para que /srv no crezca sin fin), que se hace con find -mtime en la lección 03-03; automatización con cron (03-07); y destino remoto, porque una copia en el mismo disco que el original no protege contra un fallo de hardware (05-08).

Cómo decírselo a Luis: su procedimiento hace el gesto de copiar pero no cumple ninguna de las tres propiedades de una copia útil —única, verificable y restaurable—. Y la más grave es la primera: al usar un nombre fijo, la copia buena se destruye justo antes de que la necesites.

Solución 3

Elección del formato: zip. Marta trabaja en Windows y va a abrir los archivos con Excel. Aunque en Linux tar.gz conserva mejor los metadatos, aquí eso no aporta nada —son ficheros de datos, no ejecutables— y sí supondría que Marta tuviera que instalar una herramienta para abrirlo. Windows abre .zip de forma nativa con doble clic. La compatibilidad con el destinatario manda sobre la pureza técnica.

# 1. Preparar el directorio de envío
operador@srv-tramontana:~$ mkdir -p /tmp/envio-marta

# 2. Copiar los datos preservando fechas
operador@srv-tramontana:~$ cp -p ~/datos/reservas.csv ~/datos/casas.txt /tmp/envio-marta/

# 3. Redactar el informe de contenido
operador@srv-tramontana:~$ cat > /tmp/envio-marta/LEEME.txt <<'FIN'
PAQUETE DE DATOS - TRAMONTANA RESERVAS
Generado el 2026-08-18 por el equipo de sistemas

CONTENIDO
---------
reservas.csv  Reservas registradas. Separador: punto y coma (;)
              Columnas: id;fecha;casa;huesped;noches;importe
casas.txt     Listado de casas rurales disponibles

CÓMO ABRIR reservas.csv EN EXCEL
--------------------------------
El archivo usa punto y coma como separador. Si al abrirlo todo
aparece en una sola columna, usa Datos > Texto en columnas y
selecciona "punto y coma" como delimitador.

VERIFICACIÓN
------------
El paquete incluye un archivo .sha256 con la huella digital.
FIN

(Ese cat > fichero <<'FIN' es un here document: escribe todo el bloque en el archivo. Se explica en el Módulo 3; aquí lo usas como herramienta.)

# 4. Empaquetar en zip, desde dentro del directorio para no arrastrar rutas
operador@srv-tramontana:~$ cd /tmp/envio-marta
operador@srv-tramontana:/tmp/envio-marta$ zip /tmp/datos-tramontana-2026-08-18.zip *
  adding: LEEME.txt (deflated 48%)
  adding: casas.txt (deflated 41%)
  adding: reservas.csv (deflated 67%)

# 5. Verificar el contenido del paquete
operador@srv-tramontana:/tmp/envio-marta$ unzip -l /tmp/datos-tramontana-2026-08-18.zip
Archive:  /tmp/datos-tramontana-2026-08-18.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      782  2026-08-18 11:44   LEEME.txt
      418  2026-08-17 19:40   casas.txt
     1204  2026-08-18 07:55   reservas.csv
---------                     -------
     2404                     3 files

# 6. Suma de comprobación
operador@srv-tramontana:/tmp/envio-marta$ cd /tmp
operador@srv-tramontana:/tmp$ sha256sum datos-tramontana-2026-08-18.zip > datos-tramontana-2026-08-18.zip.sha256
operador@srv-tramontana:/tmp$ cat datos-tramontana-2026-08-18.zip.sha256
3a7f1c9e2b8d4056f1a3c7e9b2d5f804a6c1e3b7d9f2a5c8e0b4d7f1a3c6e9b2  datos-tramontana-2026-08-18.zip

Detalles del procedimiento que merecen comentario:

  • cd al directorio y zip * en vez de zip -r /tmp/x.zip /tmp/envio-marta: así el paquete contiene los tres archivos en su raíz, sin la jerarquía tmp/envio-marta/ dentro. Es el equivalente del -C de tar.
  • cp -p conserva las fechas originales de los datos, visibles en el listado del zip. Marta puede ver que casas.txt es de ayer y reservas.csv de esta mañana.
  • El LEEME resuelve por adelantado la pregunta que Marta habría hecho por teléfono: por qué el CSV se ve mal en Excel. El separador punto y coma es el que usa reservas.csv, y en un Excel con configuración regional española suele funcionar directamente, pero conviene documentarlo.
  • La suma de comprobación va en un archivo aparte, no dentro del zip: tiene que poder verificarse sin abrir el paquete.

Nota importante para el mundo real: reservas.csv contiene nombres de huéspedes, es decir, datos personales. Enviar ese archivo fuera del servidor por correo o por un canal no cifrado tiene implicaciones de protección de datos. En un entorno real, este envío debería ir cifrado y contar con la aprobación del responsable de protección de datos. Volveremos sobre el cifrado de archivos en la lección 06-05.

Conclusión

Ya escribes en el disco, y lo haces con red de seguridad.

  • touch crea archivos vacíos y manipula marcas de tiempo, y su ctime siempre delata la manipulación.
  • mkdir -p es idempotente y crea árboles completos; rmdir es seguro por diseño porque solo borra lo vacío.
  • cp sobrescribe en silencio; -a es la opción para copias fieles; y la trampa de la barra final y del destino preexistente produce resultados distintos con el mismo comando.
  • mv es instantáneo dentro del mismo sistema de archivos porque solo cambia una entrada de directorio, y es copiar-y-borrar, lento y no atómico, cuando cruza a otro.
  • rm es irreversible, rm -rf con una variable vacía ha borrado sistemas enteros, y las defensas son mirar antes, -I, comillas y, sobre todo, copias de seguridad.
  • rename -n renombra por lotes con simulación previa.
  • rsync -av es el cp correcto para directorios: incremental, verificable, reanudable, con --dry-run y con la barra final que sí importa.
  • tar empaqueta preservando permisos; se lista con -t antes de extraer y se usa -C para no arrastrar rutas absolutas.
  • gzip por defecto, xz para distribuir, zip para Windows, y sabes justificar la elección.
  • Y has preparado un paquete de producción completo: verificado, con suma de comprobación y probado antes de enviarlo.

Ya sabes mover archivos de sitio. Falta lo que hay dentro de ellos. En la próxima lección, Visualización y Edición de Archivos, aprenderás a mirar el contenido sin abrir un editor con cat, less, head y tail —incluido tail -F para seguir errores.log en vivo mientras ocurre una incidencia—, y a editarlo con nano a fondo y con el vim de supervivencia que necesitarás el día que entres en un servidor donde no haya otra cosa. Establecerás además una convención que el curso usará a partir de ahí: copia de seguridad del fichero de configuración antes de tocarlo. Y verás cómo comparar dos versiones de app.conf con diff para saber exactamente qué cambió, que es la pregunta que se hace siempre después de que algo deje de funcionar.

Curso de Linux: De Principiante a Administrador de Sistemas

Módulo 1: Introducción a Linux

Módulo 2: Comandos Básicos de Linux

Módulo 3: Habilidades Avanzadas en la Línea de Comandos

Módulo 4: Scripting en Shell

Módulo 5: Administración del Sistema

Módulo 6: Redes y Seguridad

Módulo 7: Temas Avanzados

Módulo 8: Proyectos Prácticos

© Copyright 2026. Todos los derechos reservados