- -P
- muestra la ruta física, con los enlaces simbólicos resueltos
- -L
- muestra la ruta lógica, conservando los enlaces simbólicos (predeterminado)
pwd¿dónde estoy?
pwd -Pla ruta real cuando has llegado a través de un enlace simbólico
Comandos de Linux por tarea, desde archivos y permisos hasta redes, systemd y procesamiento de texto. Cada entrada incluye opciones, ejemplos para copiar y notas para macOS.
Última verificación: 2026-10-18, verificado con los manuales de GNU coreutils 9.x, util-linux, procps-ng, iproute2, systemd y bash 5.2; las notas de macOS, con las páginas man de macOS 26.
Lee archivos, recorre logs página a página, edita en la terminal y compara versiones.
cat /etc/os-releasemostrar un archivo
cat part1.txt part2.txt > whole.txtconcatenar
cat -A script.sh | headdetectar tabuladores ocultos y finales de línea ^M de Windows
macOS/BSD: cat de macOS no tiene -A; usa cat -vet para obtener lo mismo.
tac access.log | headlas líneas de log más recientes primero
macOS/BSD: No existe en macOS; usa tail -r file.
less /var/log/syslogleer un log
journalctl -u nginx | less -Slíneas anchas sin ajustar
head -n 20 data.csvla cabecera y las primeras filas
head -c 512 file.bin | xxdechar un vistazo al principio de un binario
macOS/BSD: head de macOS no acepta cantidades negativas.
tail -n 50 app.loglas últimas 50 líneas
tail -F /var/log/nginx/access.logvigilar un log que se rota
tail -n +2 data.csvsaltarse la línea de cabecera de un CSV
sudo nano /etc/hostseditar un archivo del sistema
La barra de atajos de la parte inferior de la pantalla muestra las teclas; ^ significa Ctrl y M- significa Alt.
vim +42 app.pyabrir en la línea 42
diff -u old.conf new.confvista de cambios legible
diff -rq dir1/ dir2/qué archivos difieren entre dos árboles
diff <(sort a.txt) <(sort b.txt)comparar tras ordenar, mediante sustitución de procesos
make 2>&1 | tee build.logver una compilación y guardar un log
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.confañadir a un archivo propiedad de root (sudo echo >> falla porque la redirección la hace el shell)
printf '%s\n' "$var"mostrar una variable de forma segura, aunque empiece por -n
printf '%-12s %6.2f\n' disk 93.5columnas alineadas
echo -e y echo -n se comportan distinto según el shell; printf se comporta igual en todas partes.
column -t -s, data.csv | less -Sleer un CSV sencillo como tabla
mount | column -talinear una salida separada por espacios
xxd image.png | headhexadecimal y ASCII lado a lado
hexdump -C file.bin | headvolcado hexadecimal canónico
xxd forma parte de los paquetes de vim; hexdump está en util-linux (bsdextrautils en Debian/Ubuntu recientes).
strings -n 8 firmware.bin | lessencontrar cadenas de versión, URL y rutas
Forma parte de binutils en Linux.
Consulta y cambia quién puede leer, escribir y ejecutar un archivo.
ls -l deploy.sh-rwxr-x--- 1 alice devs 812 Oct 18 09:12 deploy.sh
El primer carácter es el tipo (- archivo, d directorio, l enlace simbólico). Después vienen tres tríos: propietario, grupo y el resto. r=4, w=2, x=1, así que rwxr-x--- es 750.
chmod 644 index.htmlpropietario lectura/escritura, todos lectura: archivos normales
chmod 755 deploy.shpropietario todo, los demás lectura/ejecución: scripts y directorios
chmod 600 ~/.ssh/id_ed25519clave privada legible solo por ti; ssh rechaza claves con permisos más laxos
chmod +x script.shhacer ejecutable un script
chmod go-w filequitar la escritura al grupo y a los demás
chmod -R u=rwX,go=rX site/la X mayúscula solo da permiso de ejecución a los directorios y a los archivos que ya lo tenían
Construye modos simbólicos y octales con la calculadora de chmod →
find site/ -type d -exec chmod 755 {} +la solución correcta, parte 1: directorios a 755
find site/ -type f -exec chmod 644 {} +parte 2: archivos a 644
Peligro: Da permiso de escritura sobre todo el árbol a cualquier usuario y a cualquier servicio comprometido de la máquina, marca todos los archivos como ejecutables y hace que OpenSSH rechace las claves si ~/.ssh tiene 777. Aplicado a /etc o /usr puede romper sudo y el sistema. Corrige el propietario con chown, o usa los dos comandos find.
sudo chown -R www-data:www-data /var/www/sitedar la raíz web al usuario del servidor web
sudo chown "$USER": file.txtapropiarte de un archivo creado por root
Peligro: sudo chown -R sobre /, /usr o /etc elimina los bits setuid y los propietarios de los que dependen sudo, passwd y los servicios; recuperarse suele implicar reinstalar. Revisa bien la ruta.
chgrp -R developers /srv/sharedasignar una carpeta compartida al grupo de un equipo
umaskmuestra la máscara actual, normalmente 0022
umask 077archivos nuevos a 600 y directorios a 700 en este shell
La máscara quita bits: los archivos parten de 666 y los directorios de 777, así que 022 da 644 y 755.
sudo systemctl restart nginxun comando de administración
sudo !!volver a ejecutar el comando anterior con sudo
sudo -u postgres psqlejecutar como usuario de un servicio
su - deployiniciar sesión como deploy con su entorno
sudo su -shell de root cuando root no tiene contraseña (sudo -i hace lo mismo)
setfacl -m u:alice:rw report.xlsxalice puede leer y escribir, sin cambiar el grupo
getfacl report.xlsxmostrar todas las entradas
setfacl -R -m g:devs:rwX /srv/appun grupo obtiene acceso a todo un árbol
Un + al final de la cadena de permisos de ls -l indica que el archivo tiene una ACL.
sudo chattr +i /etc/resolv.confnadie, ni siquiera root, puede modificarlo ni borrarlo hasta que se le quite con -i
lsattr /etc/resolv.confmostrar los atributos; i significa inmutable
Compatible con ext4, XFS y Btrfs. Si aparece "Operation not permitted" incluso como root, revisa lsattr.
Averigua qué se está ejecutando, detenlo y ejecuta cosas en segundo plano.
ps aux | grep [n]ginxel truco de [n] evita que el propio grep salga en los resultados
ps aux --sort=-%mem | headlos procesos que más memoria usan
ps -o pid,ppid,etime,cmd -p 1234cuánto tiempo lleva en ejecución un proceso
macOS/BSD: ps de macOS no tiene --sort; usa ps aux -m (por memoria) o ps aux -r (por CPU).
pstree -pcon los PID
pstree -p 1234qué procesos ha lanzado un proceso
top -b -n 1 | head -20captura que puedes pegar en una incidencia
macOS/BSD: top de macOS es un programa distinto: ordena con top -o cpu o top -o mem.
htop -u www-datasolo los procesos de un usuario
Instálalo con apt install htop / dnf install htop.
pgrep -a nginxPID y líneas de comandos
pgrep -f 'python manage.py runserver'encontrar un script por sus argumentos
macOS/BSD: En macOS, -a significa "incluir los ancestros"; usa pgrep -lf para ver los nombres y los argumentos.
pkill -f "node server.js"detener una app de Node
pkill -HUP nginxenviar una señal de recarga
pgrep -af nodever qué coincidiría con -f antes de matar nada
Los patrones son expresiones regulares que coinciden en cualquier parte del nombre; pkill node también afecta a nodejs-helper. Compruébalo antes con pgrep.
kill 1234detención educada
kill -9 1234último recurso cuando se ignora TERM
kill %1matar el trabajo 1 de este shell
Prueba primero con kill a secas y espera unos segundos: -9 se salta la limpieza, así que pueden quedar archivos temporales, bloqueos y datos a medio escribir.
killall firefoxtodos los procesos de Firefox
En Linux está en el paquete psmisc.
jobslistar los trabajos de este shell con su número
bg %1reanudar el trabajo 1 en segundo plano
fg %1devolverlo al primer plano
Ctrl+Z suspende el programa en primer plano (se detiene hasta que uses bg o fg).
./long-export.sh > export.log 2>&1 &lanzarlo y recuperar el prompt
waiten un script, esperar a que terminen los trabajos en segundo plano
nohup ./server > server.log 2>&1 &sobrevive al cierre de la sesión SSH
Para cualquier cosa de larga duración, un servicio de systemd (consulta Servicios y logs) o tmux es más robusto.
disown -h %1se te olvidó nohup: pásalo a segundo plano con bg y luego usa disown
tmux new -s deployiniciar una sesión con nombre
tmux attach -t deployvolver a conectarse tras perder el SSH
Instálalo con tu gestor de paquetes. GNU screen es la alternativa más antigua (Ctrl+A d para desconectarte, screen -r para volver a conectarte).
nice -n 19 tar -czf backup.tgz /datacopia de seguridad que no estorba
sudo renice -n -5 -p 1234subir la prioridad de un proceso en ejecución
El valor nice va de -20 (máxima prioridad) a 19 (mínima). Solo root puede bajar de 0.
timeout 30s curl -s https://example.com/healthrendirse al cabo de 30 segundos
timeout -s KILL 5m ./job.shmatarlo a la fuerza al cabo de cinco minutos
Sale con el código 124 cuando se alcanza el límite de tiempo.
watch -n 2 df -hver cómo se llena el disco
watch -d 'ss -s'-d resalta lo que ha cambiado
sudo lsof -i :8080qué está escuchando en el puerto 8080
sudo lsof +L1archivos borrados que siguen abiertos (disco lleno pero du no muestra nada)
lsof -p 1234todos los archivos que tiene abiertos un proceso
sudo fuser -vm /mnt/usbpor qué umount dice "target is busy"
sudo fuser -v 8080/tcpel proceso de un puerto TCP
Peligro: fuser -k mata sin preguntar todos los procesos que usan el destino; en un punto de montaje, eso puede incluir tu propio shell.
time ./build.shreal = tiempo de reloj, user + sys = tiempo de CPU
strace -f -e trace=openat ./app 2>&1 | grep -v ENOENT¿qué archivos abre realmente?
sudo strace -p 1234¿en qué se ha quedado atascado un proceso colgado?
Versión del sistema operativo, kernel, CPU, memoria, hardware, hora y carga.
uname -rp. ej. 6.8.0-45-generic
uname -mqué binario descargar: x86_64 o aarch64
cat /etc/os-releaseNAME, VERSION_ID e ID en cualquier distribución con systemd
lsb_release -aalternativa en Debian/Ubuntu, si está instalado
macOS/BSD: macOS: sw_vers.
hostnamectlnombre del equipo, sistema operativo, kernel, virtualización
sudo hostnamectl set-hostname web01renombrar la máquina
uptimecarga media de los últimos 1, 5 y 15 minutos
La carga es el número de procesos en ejecución o en espera. Compárala con el número de CPU (nproc): una carga de 4 en 4 núcleos significa que están totalmente ocupados.
free -hfíjate en la columna "available", no en "free"
macOS/BSD: macOS: vm_stat, o top -l 1 | grep PhysMem.
Linux usa la RAM sobrante como caché de disco, así que "free" parece bajo en una máquina sana. "available" es lo que los programas aún pueden obtener.
lscpumodelo, sockets, núcleos, hilos, flags
make -j"$(nproc)"usar todos los núcleos disponibles
macOS/BSD: macOS: sysctl -n hw.ncpu y sysctl -n machdep.cpu.brand_string.
lspci -k | grep -A3 -i vgala tarjeta gráfica y el driver que usa
lsusb¿se detecta siquiera el dispositivo USB?
sudo dmidecode -t memory | grep -i sizeRAM instalada por ranura
sudo lshw -shortuna línea por dispositivo
sudo dmesg -T | tail -30qué acaba de pasar (USB conectado, errores de disco)
sudo dmesg -T | grep -i 'out of memory'¿ha detenido el OOM killer tu app?
grep MemAvailable /proc/meminfomemoria disponible en kB
grep -c ^processor /proc/cpuinfonúmero de CPU lógicas
cat /proc/1234/statusestado y memoria de un proceso
vmstat 1 5r = cola de ejecución, si/so = uso de swap, wa = espera de E/S
iostat -xz 1uso por disco (%util) y latencia (await)
iostat viene en el paquete sysstat.
date '+%Y-%m-%d %H:%M:%S'marca de tiempo para logs
date +%ssegundos desde el 1970-01-01 UTC
date -d @1700000000de marca de tiempo a fecha (GNU)
date -d '2 days ago' +%Ffecha relativa (GNU)
macOS/BSD: date de macOS no tiene -d. Usa date -r 1700000000 para una marca de tiempo, date -v-2d para "hace 2 días" y date -j -f '%Y-%m-%d' 2026-10-18 +%s para interpretar una fecha.
Convierte marcas de tiempo con el conversor de timestamps Unix →
timedatectlhora local, UTC, zona horaria, ¿sincronizado por NTP?
timedatectl list-timezones | grep Americaencontrar el nombre de la zona
sudo timedatectl set-timezone America/Torontocambiarla
Espacio libre, qué lo ocupa, particiones, montaje y formateo.
df -htodos los sistemas de archivos montados
df -h .el sistema de archivos en el que está este directorio
df -i¿"No space left" con bytes libres? Puede que te hayas quedado sin inodos
macOS/BSD: En macOS, -T filtra por tipo en vez de mostrarlo.
du -sh /var/logtamaño de una carpeta
du -h -d 1 | sort -hsubcarpetas, la más grande al final (funciona en GNU y macOS)
sudo du -xh -d 1 / | sort -h | taillos directorios de primer nivel más grandes
macOS/BSD: du de macOS tiene -d pero no --max-depth.
sudo ncdu -x /navega con las flechas, d para borrar
Instálalo con apt install ncdu / dnf install ncdu.
lsblkdiscos, particiones, tamaños y puntos de montaje
lsblk -fqué partición es ext4/xfs, y su UUID
macOS/BSD: macOS: diskutil list.
sudo blkid /dev/sdb1UUID y TYPE, para /etc/fstab
findmntárbol de montajes con sus opciones
findmnt -T /var/lib/dockerqué sistema de archivos contiene esta ruta
sudo findmnt --verifybuscar errores en /etc/fstab antes de reiniciar
sudo mount /dev/sdb1 /mnt/usbmontar un pendrive USB (el directorio debe existir)
sudo mount -o remount,rw /hacer escribible una raíz de solo lectura
sudo mount -t nfs nas:/export /mnt/nasmontar un recurso compartido NFS
sudo umount /mnt/usbdespués de esto ya puedes desconectarlo
sudo umount -l /mnt/nasdiferido: lo desconecta ya y lo limpia cuando deje de estar ocupado
"target is busy" significa que un proceso lo está usando (a menudo tu propio shell, situado en ese directorio): encuéntralo con fuser -vm o lsof.
UUID=3f6c... /data ext4 defaults,nofail 0 2una línea por sistema de archivos; nofail permite que el arranque continúe si falta el disco
sudo mount -amontar ya todo lo que hay en fstab: pruébalo antes de reiniciar
Una errata en fstab puede hacer que el siguiente arranque entre en modo de emergencia. Ejecuta siempre sudo mount -a (o findmnt --verify) después de editarlo.
sudo fdisk -ltodos los discos y sus particiones
sudo parted /dev/sdb printtipo de tabla de particiones (gpt/msdos) y distribución
Peligro: Escribir una tabla de particiones (w en fdisk, mklabel en parted) deja inaccesibles los datos que hubiera en ese disco. Confirma antes el nombre del dispositivo con lsblk; /dev/sda y /dev/sdb se intercambian con facilidad.
sudo mkfs.ext4 -L data /dev/sdb1ext4 con etiqueta
sudo mkfs.vfat -F 32 /dev/sdc1FAT32 para un pendrive USB que puedan leer otros dispositivos
Peligro: Borra al instante el sistema de archivos del destino, sin confirmación si el dispositivo no está montado. Comprueba el dispositivo con lsblk -f; formatear /dev/sda en lugar de /dev/sda1, o el disco equivocado, lo destruye.
sudo fsck -f /dev/sdb1forzar una comprobación completa de una partición desmontada
Peligro: Nunca ejecutes fsck en un sistema de archivos montado en lectura/escritura: puede corromperlo. Desmóntalo antes o, si es el sistema de archivos raíz, arranca desde un medio de rescate.
sudo dd if=ubuntu.iso of=/dev/sdX bs=4M status=progress conv=fsynccrear un USB de arranque (sustituye sdX por el disco entero, no por una partición)
dd if=/dev/zero of=test.img bs=1M count=100crear un archivo de 100 MB
Peligro: dd sobrescribe el destino of= sin preguntar. Intercambiar if= y of=, o elegir el /dev/sdX equivocado, borra ese disco. Compruébalo con lsblk justo antes de ejecutarlo.
macOS/BSD: macOS: usa como destino /dev/rdiskN (de diskutil list) tras diskutil unmountDisk, usa bs=4m y pulsa Ctrl+T para ver el progreso.
sync && sudo umount /mnt/usbantes de sacar una unidad USB
swapon --showswap actual
sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfileañadir un archivo de swap de 2 GB (añádelo a /etc/fstab para conservarlo)
En Btrfs, un archivo de swap necesita pasos adicionales (btrfs filesystem mkswapfile en versiones recientes de btrfs-progs).
shred -u -n 3 secrets.txtsobrescribir tres veces y luego borrar
Peligro: Irreversible. Además, no es fiable en SSD, en sistemas de archivos con journaling o copy-on-write (Btrfs, ZFS) ni en nada con snapshots; para una protección real, usa cifrado de disco completo.
Direcciones IP, rutas, puertos abiertos, peticiones HTTP, DNS, SSH y transferencia de archivos.
ip -br auna línea por interfaz: nombre, estado, direcciones
ip a show eth0una interfaz en detalle
hostname -Isolo las direcciones IP
macOS/BSD: macOS: ifconfig, o ipconfig getifaddr en0.
ip sustituye al antiguo ifconfig (net-tools), que muchas distribuciones ya no instalan.
ip rrutas; "default via" es la puerta de enlace
ip route get 1.1.1.1qué interfaz y qué puerta de enlace usa un destino
sudo ip route add 10.20.0.0/16 via 192.168.1.1añadir una ruta (se pierde al reiniciar)
ip linkinterfaces y direcciones MAC
sudo ip link set eth0 down && sudo ip link set eth0 upreiniciar una interfaz
Peligro: Si desactivas la interfaz por la que estás conectado por SSH, se corta tu sesión.
sudo ss -tulpntodos los puertos en escucha y su programa
ss -tn state established '( dport = :443 )'conexiones establecidas al puerto 443
ss -stotales de conexiones
macOS/BSD: macOS: lsof -iTCP -sTCP:LISTEN -n -P, o netstat -an.
ss sustituye a netstat; netstat -tulpn sigue funcionando donde está instalado net-tools.
curl -I https://example.comlínea de estado y cabeceras
curl -LO https://example.com/file.tar.gzdescargar siguiendo redirecciones
curl -s -o /dev/null -w '%{http_code}\n' https://example.comsolo el código de estado
curl -fsSL https://example.com/install.sh -o install.shdescargar un script para leerlo antes de ejecutarlo
curl -H 'Content-Type: application/json' -d '{"name":"Ada"}' https://api.example.com/usersenviar JSON por POST
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/mecomillas dobles para que $TOKEN se expanda
curl -X DELETE https://api.example.com/users/42otros métodos
wget -c https://example.com/big.isoreanudar tras un corte de conexión
wget -qO- https://example.com/data.json | jq .pasarlo directamente a otro comando
macOS/BSD: No viene en macOS de serie; usa curl -LO (curl -C - -LO para reanudar).
dig +short example.comsolo los registros A
dig MX example.comservidores de correo
dig @1.1.1.1 example.compreguntar a un resolver concreto (sin pasar por la caché local)
dig -x 8.8.8.8búsqueda inversa
dig +trace example.comseguir la delegación desde la raíz
Nombre del paquete: dnsutils (Debian/Ubuntu) o bind-utils (Fedora/RHEL).
host example.comA, AAAA y MX en una respuesta corta
nslookup example.com 8.8.8.8el mismo comando existe en Windows
resolvectl statusservidores DNS por interfaz
sudo resolvectl flush-cachesvaciar la caché de systemd-resolved
macOS/BSD: macOS: sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder.
Solo en sistemas que usan systemd-resolved (Ubuntu y Fedora por defecto).
ping -c 4 example.comcuatro paquetes y un resumen
En Linux y macOS, ping sigue hasta que pulsas Ctrl+C, salvo que uses -c (Windows para tras 4). Que no responda no siempre significa que esté caído: muchos hosts bloquean ICMP.
traceroute -n example.comsaltos sin consultas DNS
tracepath example.comno necesita root y también indica la MTU
macOS/BSD: macOS tiene traceroute pero no tracepath.
En Linux puede que haya que instalar traceroute; tracepath (iputils) suele estar disponible.
mtr -rw -c 100 example.cominforme tras 100 sondeos por salto
Combina ping y traceroute. Si la pérdida aparece solo en un salto intermedio, suele ser que ese router da baja prioridad a ICMP; la pérdida que continúa hasta el final es real.
ssh alice@203.0.113.10iniciar sesión
ssh -p 2222 alice@hostpuerto no estándar
ssh alice@host 'df -h'ejecutar un comando y volver
ssh -J bastion.example.com alice@10.0.0.5saltar a través de un host bastión
ssh -N -L 5432:localhost:5432 alice@db-hostconectar tu cliente de base de datos local a un Postgres remoto
ssh -N -D 1080 alice@hostnavegar a través del servidor
ssh-keygen -t ed25519 -C "you@example.com"nuevo par de claves en ~/.ssh
ssh-copy-id alice@hostañadir tu clave pública al authorized_keys del servidor
ssh-keygen -R hosteliminar una clave de host antigua tras reconstruir un servidor ("REMOTE HOST IDENTIFICATION HAS CHANGED")
Host web
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519y luego basta con: ssh web (scp y rsync también lo usan)
scp report.pdf alice@host:/tmp/subir
scp alice@host:/var/log/app.log .descargar
scp -r -P 2222 site/ alice@host:~/subir una carpeta por otro puerto
Desde OpenSSH 9.0, scp usa por debajo el protocolo SFTP. Para copias grandes o repetidas, rsync es más rápido porque solo envía los cambios.
rsync -avzP site/ deploy@host:/srv/site/la barra final en site/ copia su contenido, no la carpeta en sí
rsync -av --exclude 'node_modules' ./ /backup/app/copia de seguridad local sin lo que sobra
macOS/BSD: Las versiones recientes de macOS incluyen openrsync en lugar de rsync; las opciones habituales funcionan, algunas menos comunes no.
src/ significa "el contenido de src"; src sin barra significa "la carpeta src". Si te equivocas, acabas con carpetas anidadas (dest/src/…).
rsync -avn --delete site/ /srv/site/primero la simulación: las líneas que empiezan por "deleting" muestran lo que se borraría
rsync -av --delete site/ /srv/site/luego la ejecución real
Peligro: Borra todo lo que hay en el destino y no está en el origen. Intercambiar origen y destino, o una ruta de origen vacía o equivocada, vacía el destino. Ejecútalo siempre antes con -n.
nc -zv db.internal 5432"succeeded" o "Connection refused"/tiempo de espera agotado
nc -l 9000escuchar en un puerto para probar un firewall desde el otro lado
Las opciones cambian según la variante de netcat: la tradicional necesita nc -l -p 9000.
sudo ufw status verbosereglas y política predeterminada
sudo ufw allow 22/tcppermitir SSH (hazlo antes de enable)
sudo ufw allow from 10.0.0.0/8 to any port 5432un puerto, una red
Peligro: Si ejecutas sudo ufw enable en un servidor remoto sin haber permitido antes SSH (ufw allow OpenSSH o 22/tcp), te quedas fuera.
sudo firewall-cmd --list-allzona activa y reglas
sudo firewall-cmd --permanent --add-service=https && sudo firewall-cmd --reloadabrir HTTPS de forma permanente
sudo firewall-cmd --permanent --add-port=8080/tcpabrir un puerto
Sin --permanent, una regla dura hasta la siguiente recarga o reinicio.
nmcli device statusinterfaces y si están conectadas
nmcli device wifi listredes cercanas
nmcli device wifi connect 'MyWiFi' password 'secret'conectarse a una red
La misma tarea en los cuatro gestores de paquetes principales: Debian/Ubuntu (apt), Fedora/RHEL (dnf), Arch (pacman) y openSUSE (zypper). Antepón sudo a todo lo que modifique el sistema.
| Tarea | apt (Debian, Ubuntu) | dnf (Fedora, RHEL) | pacman (Arch) | zypper (openSUSE) |
|---|---|---|---|---|
| Actualizar las listas de paquetes # dnf las actualiza automáticamente cuando los metadatos están desfasados. En Arch, nunca ejecutes pacman -Sy y después -S pkg: las actualizaciones parciales no están soportadas; usa -Syu. | apt update | dnf makecache | pacman -Sy | zypper refresh |
| Actualizar todo # openSUSE Tumbleweed usa zypper dup. apt full-upgrade también elimina paquetes cuando hace falta para completar la actualización. | apt update && apt upgrade | dnf upgrade | pacman -Syu | zypper update |
| Instalar un paquete # | apt install nginx | dnf install nginx | pacman -S nginx | zypper install nginx |
| Instalar un archivo de paquete descargado # El ./ indica a apt que es un archivo, no un nombre de paquete, así que resuelve las dependencias (dpkg -i no lo hace). | apt install ./app.deb | dnf install ./app.rpm | pacman -U app.pkg.tar.zst | zypper install ./app.rpm |
| Desinstalar un paquete # | apt remove nginx | dnf remove nginx | pacman -R nginx | zypper remove nginx |
| Desinstalar con archivos de configuración / dependencias sin usar # | apt purge nginx && apt autoremove | dnf remove nginx && dnf autoremove | pacman -Rns nginx | zypper remove --clean-deps nginx |
| Buscar un paquete # | apt search keyword | dnf search keyword | pacman -Ss keyword | zypper search keyword |
| Ver los detalles de un paquete # | apt show nginx | dnf info nginx | pacman -Si nginx (installed: -Qi) | zypper info nginx |
| Listar los paquetes instalados # | apt list --installed | dnf list --installed | pacman -Q | zypper search --installed-only |
| Listar las actualizaciones disponibles # | apt list --upgradable | dnf check-update | checkupdates (pacman-contrib) | zypper list-updates |
| Qué paquete contiene un archivo # Para archivos que aún no están instalados: dnf provides /path, apt-file search path (requiere apt-file), pacman -F path. | dpkg -S /usr/bin/curl | rpm -qf /usr/bin/curl | pacman -Qo /usr/bin/curl | rpm -qf /usr/bin/curl |
| Listar los archivos que instaló un paquete # | dpkg -L nginx | rpm -ql nginx | pacman -Ql nginx | rpm -ql nginx |
| Fijar un paquete en su versión actual # En DNF 4, versionlock requiere el paquete del plugin versionlock. | apt-mark hold nginx | dnf versionlock add nginx | IgnorePkg = nginx in /etc/pacman.conf | zypper addlock nginx |
| Vaciar la caché de paquetes # | apt clean | dnf clean all | pacman -Sc | zypper clean |
Quién eres, quién ha iniciado sesión y cómo gestionar cuentas.
iduid, gid y todos los grupos a los que perteneces
id aliceotro usuario
wquién está conectado y qué está ejecutando
last -n 10inicios de sesión y reinicios recientes
sudo lastb -n 10intentos de inicio de sesión fallidos recientes (Linux)
sudo useradd -m -s /bin/bash alice && sudo passwd alicecrearla y asignar una contraseña
En Debian/Ubuntu, adduser alice es el asistente interactivo más amigable, que configura el directorio personal y la contraseña.
sudo usermod -aG docker alicepermitir que alice use docker
sudo usermod -aG sudo aliceadministrador en Debian/Ubuntu (en Fedora/RHEL/Arch el grupo es wheel)
Peligro: Sin -a, usermod -G reemplaza todos los grupos secundarios del usuario, lo que puede quitarle el acceso a sudo. Los cambios de grupo se aplican en el siguiente inicio de sesión (o ejecuta newgrp docker).
sudo userdel -r oldusertambién borra el directorio personal y el buzón de correo
Peligro: -r borra para siempre el directorio personal y sus archivos. Haz antes una copia de seguridad o, en su lugar, bloquea la cuenta (passwd -l).
passwdcambiar la tuya
sudo passwd alicerestablecer la de otra persona
sudo passwd -l alicebloquear el inicio de sesión con contraseña (las claves SSH pueden seguir funcionando)
sudo groupadd developersgrupo nuevo
sudo gpasswd -d alice developersquitar a alice de él
groups alicelos grupos de alice
getent group sudomiembros de sudo (también funciona con LDAP)
getent passwd aliceentrada de la cuenta: UID, directorio personal, shell
sudo visudo -f /etc/sudoers.d/deployun archivo separado por regla
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myappun comando sin contraseña
visudo comprueba la sintaxis antes de guardar. Editar /etc/sudoers con un editor normal y cometer una errata puede dejar a todo el mundo sin sudo.
sudo chage -l alicefechas del último cambio y de caducidad
sudo chage -M 90 alicecaduca cada 90 días
tar, gzip, xz, zip y sumas de comprobación.
tar -czf site-2026-10-18.tar.gz site/archivo comprimido con gzip de una carpeta
tar -cJf logs.tar.xz --exclude='*.tmp' logs/archivo xz más pequeño, sin los archivos temporales
tar -xf archive.tar.gztar de GNU y tar de macOS detectan la compresión por sí solos
tar -xzf app.tar.gz -C /opt/app --strip-components=1en una carpeta, sin el directorio contenedor
tar -tf backup.tar.gz | lessver qué contiene sin extraerlo
tar -xf backup.tar.gz etc/nginx/nginx.confsacar un archivo (con la ruta que muestra -t)
tar --zstd -cf data.tar.zst data/mucho más rápido que xz, con una tasa similar a gzip -9 o mejor
zstd -d file.zstdescomprimir un solo archivo
Requiere GNU tar 1.31+ (o un bsdtar reciente) y el programa zstd.
gzip -k access.logcrea access.log.gz y conserva el original
zcat access.log.gz | grep 404leer sin descomprimir en el disco
zgrep 500 access.log.*.gzbuscar con grep directamente en logs rotados
Sin -k, gzip sustituye el archivo por la versión .gz.
xz -T0 -k big.sqltodos los núcleos de CPU, conservando el original
unxz big.sql.xzdescomprimir
zip -r site.zip site/comprimir una carpeta en zip
zip -r site.zip site/ -x '*.git*' '*/node_modules/*'excluir rutas
zip -e cifra con el antiguo esquema ZipCrypto, que es débil. Para una confidencialidad real, usa 7z o gpg.
unzip files.zip -d files/en una carpeta
unzip -l files.zipsolo listar el contenido
unzip -o files.zipsobrescribir sin preguntar
7z x archive.7zextraer con las rutas completas
7z a -p backup.7z docs/archivo cifrado con AES-256 (pide una contraseña)
7z l archive.rarlistar el contenido de muchos formatos
Paquete: p7zip-full / 7zip en Debian/Ubuntu, p7zip o 7zip en Fedora/Arch.
sha256sum ubuntu.isocompáralo con el hash de la página de descarga
sha256sum -c SHA256SUMS --ignore-missingcomprobar todos los archivos de la lista que realmente tienes
macOS/BSD: macOS: shasum -a 256 file (y shasum -a 256 -c SUMSFILE).
split -b 100M backup.tar.gz backup.part.backup.part.aa, .ab, …
cat backup.part.* > backup.tar.gzvolver a unirlas
Busca archivos por nombre, antigüedad o tamaño, y busca texto dentro de los archivos.
find . -name '*.log'pon el patrón entre comillas para que el shell no lo expanda antes
find / -iname 'nginx.conf' 2>/dev/nullbuscar en todas partes ocultando los errores de permisos
find . -maxdepth 1 -type dsubdirectorios inmediatos
find . -type l -xtype lenlaces simbólicos rotos (GNU)
find . -type f -emptyarchivos vacíos
find /var/log -type f -mtime +30logs de más de 30 días
find . -type f -mmin -15qué ha cambiado en los últimos 15 minutos
sudo find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/nullarchivos de más de 500 MB en el sistema de archivos raíz
find . -name '*.sh' -exec chmod +x {} +{} + pasa muchos archivos por comando (rápido)
find . -name '*.py' -exec grep -l 'TODO' {} +qué archivos de Python contienen TODO
find . -name '*.jpg' -print0 | xargs -0 -P4 -n 20 jpegoptimprocesamiento en paralelo, seguro con espacios en los nombres
find /tmp/app -name '*.tmp' -mtime +7 -printpaso 1: listar lo que coincide
find /tmp/app -name '*.tmp' -mtime +7 -deletepaso 2: el mismo comando con -delete al final
Peligro: El orden importa: -delete actúa allí donde aparece, así que find . -delete -name "*.tmp" borra todo lo que hay bajo . antes de que se llegue a aplicar el filtro por nombre. Pon -delete al final y ejecútalo antes con -print.
find /srv -type f -perm -o+warchivos con escritura para todos
sudo find / -xdev -perm -4000 -type f 2>/dev/nullprogramas setuid
locate -i nginx.confmucho más rápido que find /
sudo updatedbactualizar el índice ahora
Lo proporciona plocate o mlocate; el índice se reconstruye a diario, así que puede que los archivos creados hoy no aparezcan hasta que se ejecute updatedb.
grep -n 'ERROR' app.loglíneas que coinciden, con su número
grep -v '^#' nginx.conf | grep -v '^$'configuración sin comentarios ni líneas en blanco
grep -c 'Failed password' /var/log/auth.logcontar los inicios de sesión SSH fallidos
grep -rn 'TODO' src/cada TODO con su archivo y línea
grep -rl --include='*.php' 'mysql_connect' .qué archivos PHP siguen usando una API antigua
grep -rn --exclude-dir={.git,node_modules} 'apiKey' .omitir carpetas que meten ruido
grep -C 3 'Traceback' app.log3 líneas antes y después
grep -A 20 'Exception' app.logla traza de la pila tras el error
grep -E 'error|warn' app.logcualquiera de las dos palabras (regex extendida)
grep -Eo '[0-9]{1,3}(\.[0-9]{1,3}){3}' access.log | sort | uniq -c | sort -rn | headlas IP más frecuentes de un log
grep -P '\d{4}-\d{2}-\d{2}' file\d al estilo de Perl (grep de GNU)
macOS/BSD: -E funciona en todas partes; -P (PCRE) es una función de GNU y no está disponible en todas las versiones de macOS.
type llte dice si es un alias, una función, un builtin o un archivo
command -v docker >/dev/null || echo "docker missing"comprobación portable en scripts
which -a python3todos los python3 del PATH, por orden
Corta, filtra, ordena, cuenta, transforma y reestructura texto y JSON.
sed 's/http:/https:/g' links.txtmuestra el resultado; el archivo no cambia
sed 's|/usr/local|/opt|g' paths.txtcualquier delimitador, útil para rutas
sed -E 's/([0-9]+)px/\1rem/g' style.cssreutilizar un grupo capturado
sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_configsed de GNU
sed -i.bak 's/foo/bar/g' config.iniconserva config.ini.bak; funciona en GNU y macOS
macOS/BSD: sed de macOS exige un argumento después de -i: sed -i '' 's/foo/bar/g' file. sed de GNU interpreta '' como el script, así que la única forma que funciona en ambos es -i.bak.
sed -n '100,120p' big.logde la línea 100 a la 120
sed '/^\s*#/d; /^$/d' app.confquitar comentarios y líneas en blanco (\s de GNU)
sed -n '/BEGIN CERT/,/END CERT/p' bundle.pemtodo lo que hay entre dos marcadores
awk '{print $1}' access.logprimera columna (IP del cliente)
awk -F: '{print $1, $7}' /etc/passwdusuario y shell
awk -F, 'NR>1 {print $2}' data.csvsegunda columna de un CSV, sin la cabecera (solo CSV sencillos: sin comas entre comillas)
awk '$9 >= 500' access.loglíneas en las que el campo 9 (estado) es 5xx
awk '{s += $2} END {print s}' sales.txtsuma de la columna 2
awk '{c[$1]++} END {for (k in c) print c[k], k}' access.log | sort -rn | headrecuento por valor, los 10 primeros
cut -d, -f1,3 data.csvcolumnas 1 y 3
cut -d: -f1 /etc/passwdtodos los nombres de usuario
cut -c1-10 filelos 10 primeros caracteres de cada línea
cut trata cada delimitador como un corte de campo, así que dos espacios equivalen a un campo vacío. Para salidas alineadas con espacios, usa awk.
du -sh * | sort -hcarpetas por tamaño
sort -t, -k3,3nr data.csvCSV por la columna 3, numérico, descendente
sort -u emails.txt > unique.txtordenado y sin duplicados
sort ips.txt | uniq -c | sort -rn | headlas 10 líneas más frecuentes
uniq solo agrupa duplicados contiguos, así que ordena primero.
wc -l access.lognúmero de líneas
ls | wc -lcuántas entradas hay en esta carpeta
grep -c '' filerecuento de líneas que incluye una última línea sin salto de línea
tr 'a-z' 'A-Z' < in.txta mayúsculas
tr -d '\r' < windows.txt > unix.txtquitar los finales de línea CRLF de Windows
tr -s ' ' < filereducir los espacios repetidos a uno
tr '\n' ',' < list.txtunir líneas con comas
tr solo lee la entrada estándar, así que redirige el archivo con <.
find . -name '*.log' -print0 | xargs -0 rm -fborrar de forma segura los archivos encontrados
cat urls.txt | xargs -n 1 -P 4 curl -sOdescargar 4 a la vez
ls *.png | xargs -I {} cp {} /backup/{}un comando por elemento
macOS/BSD: xargs de GNU ejecuta el comando una vez aunque la entrada esté vacía, salvo que uses -r; xargs de macOS omite la entrada vacía por defecto y acepta -r por compatibilidad.
jq . response.jsonformatear de forma legible
jq -r '.items[].name' data.jsonun nombre por línea
jq -r '.[] | select(.active) | .email' users.jsonfiltrar y luego elegir un campo
curl -s https://api.github.com/repos/jqlang/jq | jq '.stargazers_count'directamente desde una API
Instálalo con apt/dnf install jq. Viene incluido en las versiones recientes de macOS.
paste -sd, ids.txttodas las líneas unidas con comas
paste names.txt emails.txtdos archivos como dos columnas
comm -12 <(sort a.txt) <(sort b.txt)en ambas
comm -23 <(sort a.txt) <(sort b.txt)solo en a.txt
seq 1 5del 1 al 5, uno por línea
seq -w 1 10con ceros a la izquierda: 01 … 10
for i in $(seq 1 3); do echo "run $i"; donecontador de un bucle
printf '%s' 'user:pass' | base64codificar (printf evita el salto de línea final)
echo dXNlcjpwYXNz | base64 -ddecodificar
base64 -w 0 image.png > image.b64sin cortes de línea (GNU corta a los 76 caracteres)
macOS/BSD: base64 de macOS no corta las líneas por defecto y no tiene -w. Usa -d para decodificar (las versiones antiguas de macOS usaban -D).
iconv -f WINDOWS-1252 -t UTF-8 old.csv > new.csvarreglar los caracteres extraños de las exportaciones de Excel
iconv -llistar las codificaciones admitidas
shuf -n 1 names.txtuna línea al azar
shuf -i 1-100 -n 5cinco números al azar del 1 al 100
Servicios de systemd: iniciar, detener, activar al arrancar y leer sus logs con journalctl.
systemctl status nginxestado, PID, memoria y las últimas líneas del log
systemctl is-active --quiet nginx && echo uppara scripts
sudo systemctl restart nginxreinicio completo
sudo systemctl reload nginxreleer la configuración sin cortar conexiones (si el servicio lo admite)
Siempre que puedas, prueba la configuración antes de reiniciar (p. ej. sudo nginx -t), para que una errata no tumbe el sitio.
sudo systemctl enable --now dockeractivar al arrancar e iniciar ya
sudo systemctl disable --now cupsdetenerlo ya y al arrancar
sudo systemctl mask bluetoothimpedir que se inicie de ninguna forma (unmask para deshacerlo)
systemctl --failedqué ha fallado
systemctl list-units --type=service --state=runningqué se está ejecutando
systemctl list-unit-files --state=enabledqué se inicia al arrancar
sudo systemctl edit nginxoverride que sobrevive a las actualizaciones de paquetes
systemctl cat nginxla unidad más todos sus overrides
sudo systemctl daemon-reloadnecesario tras editar archivos de unidad a mano
[Unit]
Description=My app
After=network.target
[Service]
User=app
WorkingDirectory=/srv/app
ExecStart=/srv/app/bin/server
Restart=on-failure
[Install]
WantedBy=multi-user.targetdespués: sudo systemctl daemon-reload && sudo systemctl enable --now myapp
journalctl -u nginx -fseguir un servicio
journalctl -u myapp --since '10 min ago'ventana reciente
journalctl -b -1 -p errerrores del arranque anterior al fallo
journalctl --disk-usagecuánto espacio ocupan los logs
sudo journalctl --vacuum-size=500Mconservar como máximo 500 MB de logs archivados
sudo journalctl --vacuum-time=14deliminar los logs archivados de hace más de dos semanas
Para un límite permanente, define SystemMaxUse= en /etc/systemd/journald.conf.
sudo tail -f /var/log/sysloglog general en Debian/Ubuntu (/var/log/messages en Fedora/RHEL)
sudo tail -f /var/log/auth.loginicios de sesión y sudo en Debian/Ubuntu (/var/log/secure en RHEL)
Algunas distribuciones (Fedora, Arch) solo guardan los logs en el journal, salvo que esté instalado rsyslog.
sudo rebootreiniciar ya
sudo shutdown -r +10 'Kernel update'reiniciar en 10 minutos, avisando a los usuarios conectados
sudo shutdown -ccancelar un apagado programado
sudo shutdown -h nowapagar
Ejecuta comandos de forma programada o una sola vez más tarde.
crontab -eabrir tu crontab en $EDITOR
crontab -llistarlo
crontab -l > crontab.bakhacer una copia de seguridad
Crea y entiende la programación con el generador de expresiones cron →
30 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1todos los días a las 02:30, guardando la salida
*/15 * * * * /usr/local/bin/check.shcada 15 minutos
0 9 * * 1-5 /usr/local/bin/report.sha las 09:00 de lunes a viernes
@reboot /usr/local/bin/startup.shuna vez al arrancar
cron se ejecuta con un PATH mínimo y sin el perfil del shell: usa rutas absolutas. Un % en el comando debe escaparse como \%.
crontab -l > ~/crontab.bak && crontab -rhacer una copia antes de eliminarlo
crontab ~/crontab.bakrestaurarlo desde un archivo
Peligro: Borra todas tus tareas de cron sin preguntar, y la r está justo al lado de la e en el teclado. Algunas implementaciones de cron ofrecen -i para preguntar antes (crontab -ri).
0 3 * * * root /usr/local/bin/cleanup.shlínea en /etc/cron.d/cleanup: fíjate en el campo adicional del usuario
ls /etc/cron.daily/scripts que run-parts ejecuta una vez al día
En Debian y Ubuntu se ignoran los archivos de /etc/cron.d cuyo nombre contiene un punto, así que llámalo backup, no backup.cron.
echo 'systemctl restart myapp' | sudo at 02:00esta noche a las 2
echo './report.sh' | at now + 30 minutesdentro de media hora
atqtareas pendientes
atrm 3cancelar la tarea 3
Requiere el paquete at y que el servicio atd esté en ejecución.
systemctl list-timerstodos los timers y cuándo se disparan la próxima vez
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
[Install]
WantedBy=timers.targetbackup.timer junto a backup.service; Persistent recupera las ejecuciones perdidas tras un tiempo apagado
systemd-analyze calendar 'Mon..Fri 09:00'comprobar qué significa una expresión OnCalendar
sleep 5 && curl -s localhost:8080/healthdar tiempo a que arranque un servicio
sleep 2mlos sufijos funcionan en GNU y en las versiones actuales de macOS
Tuberías, redirecciones, comodines, variables, historial y las teclas que más tiempo ahorran. macOS usa zsh por defecto: casi todo esto funciona también allí, salvo shopt, help y las funciones de bash 4 (macOS incluye bash 3.2).
ps aux | grep nginxfiltrar un listado
history | grep 'docker run'encontrar un comando que ejecutaste antes
set -o pipefailen scripts: una tubería falla si falla cualquier parte, no solo la última
ls -l > listing.txtsobrescribir (crea el archivo)
echo 'done' >> progress.logañadir al final
set -o noclobberhacer que > se niegue a sobrescribir archivos existentes (>| lo fuerza)
El shell vacía el archivo antes de ejecutar el comando, así que sort file > file te deja un archivo vacío. Escribe en un nombre nuevo y luego usa mv.
find / -name x 2>/dev/nulldescartar los mensajes de error
./build.sh > build.log 2>&1salida y errores en un solo archivo (el orden importa: primero >, luego 2>&1)
./build.sh &> build.logforma abreviada de bash para lo mismo
mysql mydb < dump.sqlun archivo como entrada
cat > config.yml <<'EOF'
port: 8080
host: $HOST stays literal
EOFponer 'EOF' entre comillas impide que se expandan las $variables
grep -c a <<< "banana"here-string
make && sudo make installinstalar solo si la compilación ha ido bien
cd /srv/app || exit 1detener un script si falla cd
(cd frontend && npm run build)paréntesis: un subshell, así que tu directorio no cambia
echo "Today is $(date +%A)"sustitución de comandos
echo $(( 1024 * 4 ))aritmética de enteros
diff <(ls dir1) <(ls dir2)sustitución de procesos: la salida como archivo temporal
Las comillas invertidas `command` son la forma antigua de $(command); $( ) se puede anidar y se lee mejor.
ls *.jpgtodos los JPG de esta carpeta
rm photo-??.pngphoto-01.png … photo-99.png
cp config.{yml,yml.bak}expansión de llaves: cp config.yml config.yml.bak
shopt -s globstar; ls **/*.md** coincide a cualquier profundidad (bash 4+)
Los comodines no incluyen por defecto los archivos que empiezan por punto (shopt -s dotglob lo cambia). Si nada coincide, bash pasa el patrón literalmente, salvo que esté activado shopt -s nullglob.
echo 'Cost: $5'comillas simples: no se expande nada
echo "Home is $HOME"comillas dobles: las variables se expanden y los espacios se conservan
cp "$file" "$dest/"entrecomilla siempre las variables con rutas: los espacios rompen las que no lo están
name="Ada"; echo "Hi $name"definir y usar
echo "${PORT:-8080}"valor predeterminado si no está definida o está vacía
file=report.tar.gz; echo "${file%%.*}" "${file##*/}"quitar la extensión / quitar el directorio
echo "${#name}"longitud de la cadena
export NODE_ENV=productionvisible para todos los programas iniciados desde este shell
DEBUG=1 ./appsolo para ese comando
printenv | sortlistarlas
unset DEBUGeliminar
Se pierden al cerrar el shell. Para conservarlas, pon los export en ~/.bashrc (shells interactivos) o en ~/.profile (shells de inicio de sesión).
echo "$PATH" | tr : '\n'una entrada por línea
export PATH="$HOME/.local/bin:$PATH"anteponer tu propia carpeta bin (añádelo a ~/.bashrc)
hash -rolvidar las ubicaciones de comandos en caché tras mover binarios
alias ll='ls -alF'añádelo a ~/.bashrc para conservarlo
source ~/.bashrcaplicar los cambios sin abrir otra terminal (igual que . ~/.bashrc)
\lsejecutar el ls real, saltándose un alias
grep -q root /etc/passwd; echo $?0 encontrado, 1 no encontrado, 2 error
set -euo pipefailal principio de un script: parar ante errores, variables sin definir y tuberías que fallan
sudo !!volver a ejecutar el último comando con sudo
cd !$usar el último argumento del comando anterior
!42volver a ejecutar la línea 42 del historial
^foo^barvolver a ejecutar el último comando sustituyendo foo por bar
Con HISTCONTROL=ignorespace (activo por defecto en Ubuntu como parte de ignoreboth), un comando escrito con un espacio delante no se guarda: útil para comandos con secretos.
bind -P | lesslistar todas las combinaciones de teclas
man rsyncmanual completo; / para buscar, q para salir
man 5 crontabsección 5: el formato del archivo, no el comando
help cdlos builtins de bash no tienen página man propia
apropos partitionqué comandos mencionan una palabra
#!/usr/bin/env bash
set -euo pipefail
name="${1:-world}"
if [[ -f "$name.txt" ]]; then
echo "found $name.txt"
fi
for f in *.log; do
echo "$f"
doneargumentos, una comprobación, un bucle
chmod +x script.sh && ./script.sh Adahacerlo ejecutable y ejecutarlo
bash -x script.shmostrar cada línea a medida que se ejecuta
$1 … $9 son los argumentos, "$@" son todos ellos y $# cuántos hay. [[ ]] es de bash; usa [ ] en scripts POSIX sh.
resetcuando, tras hacer cat de un archivo binario, la terminal se queda mostrando basura
¿Encontraste un problema o algo que podría mejorar? Leemos todos los mensajes y lo arreglamos rápido.
Esta guía rápida de comandos de Linux agrupa más de 200 comandos según la tarea que quieres hacer: moverte y gestionar archivos, permisos, procesos, espacio en disco, redes, paquetes, usuarios, archivos comprimidos, búsquedas, procesamiento de texto, servicios y logs de systemd, cron y los fundamentos de bash que lo unen todo. Cada entrada da la sintaxis, las opciones que de verdad vas a usar con una explicación de una línea, ejemplos para copiar y, cuando importa, un aviso. Busca por tarea (“espacio libre en disco”, “qué está usando el puerto 8080”) o por nombre de comando, y enlaza directamente a cualquier entrada.
Las opciones siguen los manuales de GNU coreutils, util-linux, procps-ng, iproute2, systemd y bash, que es lo que incluyen Ubuntu, Debian, Fedora, RHEL, Arch y openSUSE. Cuando macOS se comporta de otra manera, una nota azul explica cómo, porque sed -i, date -d, stat -c y xargs son los puntos clásicos en los que un script escrito en un sistema falla en el otro. Es una referencia para el 90 % habitual, no un sustituto de las páginas man: para las opciones poco usadas, man <comando> sigue siendo la referencia definitiva.
Empieza por la navegación y los archivos: pwd, ls, cd, mkdir, cp, mv, rm, cat y less. Después man (ayuda), sudo, grep y find para buscar, chmod y chown para los permisos, ps, top y kill para los procesos, df y du para el espacio en disco, y ssh y scp para máquinas remotas. Aprende pronto las tuberías (|) y la redirección (> y >>), porque te permiten combinar todo lo demás.
Ejecuta df -h para ver el espacio libre de cada sistema de archivos montado en unidades legibles. Para saber qué ocupa el espacio, ejecuta du -h -d 1 | sort -h dentro de un directorio: muestra las subcarpetas con las más grandes al final. Si df dice que el disco está lleno pero du no encuentra nada, probablemente un proceso mantiene abierto un archivo eliminado; sudo lsof +L1 los muestra.
Ejecuta sudo ss -tulpn para ver todos los puertos TCP y UDP en escucha con el programa que los usa, o sudo lsof -i :8080 para un solo puerto. El sudo importa: sin él solo ves los nombres de tus propios procesos. ss sustituyó a netstat, que sigue funcionando en los sistemas que tienen instalado el paquete net-tools.
kill PID envía SIGTERM, que pide al proceso que termine y le permite hacer limpieza: vaciar archivos, liberar bloqueos, cerrar conexiones. kill -9 PID envía SIGKILL, que el kernel aplica de inmediato y que el proceso no puede capturar ni ignorar, así que no hay limpieza. Usa primero kill a secas, espera unos segundos y reserva -9 para los procesos que lo ignoren.
macOS incluye sed de BSD, donde -i exige un argumento con la extensión de la copia de seguridad. En macOS escribe sed -i '' 's/old/new/g' file; en Linux, con GNU sed, el mismo comando falla porque interpreta '' como el script. La forma que funciona en ambos es sed -i.bak 's/old/new/g' file, que guarda una copia de seguridad que puedes borrar después.
Casi todos sí: las herramientas básicas vienen de los mismos proyectos GNU y util-linux en todas partes. Lo que cambia es el gestor de paquetes (apt en Debian y Ubuntu, dnf en Fedora y RHEL, pacman en Arch, zypper en openSUSE, que aparecen lado a lado en la tabla de Paquetes), algunas rutas de archivos de log, el grupo de administración (sudo frente a wheel) y la interfaz del cortafuegos (ufw frente a firewalld). Alpine y los sistemas basados en BusyBox usan versiones reducidas de las herramientas con menos opciones.
Una lista corta de comandos causa casi todo el daño: rm -rf con una ruta equivocada o vacía, dd o mkfs apuntando al disco equivocado, chmod -R 777 o chown -R sobre un directorio del sistema, rsync --delete o réplicas al estilo robocopy con el origen y el destino intercambiados, crontab -r en lugar de crontab -e, usermod -G sin -a, y find con -delete en la posición equivocada. Cada uno aparece marcado como Peligroso en la guía rápida, con la forma concreta en que sale mal.
El hábito que evita la mayor parte es ejecutar primero la versión inofensiva. Antes de rm -rf, ejecuta ls sobre la misma ruta. Antes de find … -delete, ejecuta el mismo find con -print. Antes de rsync --delete, añade -n para hacer una simulación. Antes de dd o mkfs, ejecuta lsblk y lee dos veces el nombre del dispositivo. En los scripts, escribe ${DIR:?} en lugar de $DIR para que una variable vacía detenga el script en lugar de convertir una ruta en /.
Dos ajustes de la shell también ayudan: set -euo pipefail al principio de los scripts detiene la ejecución en el primer error en lugar de seguir con un estado incorrecto, y set -o noclobber hace que > se niegue a sobrescribir un archivo existente.
macOS es Unix, pero sus herramientas de línea de comandos vienen de FreeBSD y no de GNU, y las diferencias aparecen justo cuando copias un comando de un tutorial de Linux:
• sed -i necesita un argumento en macOS (sed -i '' …); -i.bak funciona en ambos.
• date no tiene -d en macOS; usa date -r <epoch> para convertir una marca de tiempo y date -v-2d para fechas relativas.
• stat usa -f con otras letras de formato en lugar del -c de GNU.
• xargs en macOS omite por defecto la entrada vacía, mientras que GNU xargs ejecuta el comando una vez salvo que se le pase -r.
• du acepta -d 1 en ambos, pero solo GNU acepta --max-depth; ps no tiene --sort en macOS (usa ps aux -m o -r).
• head -n -5, tac, free, ip, ss, timeout y watch no vienen en macOS de serie.
Si necesitas el comportamiento de GNU en un Mac, los paquetes coreutils, gnu-sed y findutils de Homebrew instalan las versiones GNU con el prefijo g (gsed, gdate, gstat, gxargs).
ls -l muestra los permisos como diez caracteres, por ejemplo -rwxr-x---. El primero es el tipo (- archivo, d directorio, l enlace); los nueve siguientes son tres grupos de lectura, escritura y ejecución para el propietario, el grupo y todos los demás. En números, r vale 4, w vale 2 y x vale 1, sumados por grupo, así que rwxr-x--- es 750.
Modos típicos: 644 para archivos normales, 755 para directorios y scripts, 600 para claves privadas y archivos con secretos, 700 para un directorio privado como ~/.ssh. En un directorio, x significa “puede entrar”, por eso los directorios lo necesitan y los archivos normales no. La calculadora de chmod convierte entre la forma simbólica y la octal si quieres comprobar un modo antes de aplicarlo.