Jhonatan Pinheiro
Cargando página...
Jhonatan Pinheiro
Cargando página...
Jhonatan Pinheiro
Cargando página...
Tuberías y redirección, sed y awk, scripts de shell, systemd, cron, SSH, red, discos y registros: 200 ítems con ejemplos prácticos.
Ya navegas, editas e instalas paquetes. Estos 200 elementos son el punto de inflexión: combinar comandos, automatizar con scripts, administrar servicios con systemd, programar tareas, dominar SSH y diagnosticar disco, red y logs.
Es el conjunto que separa a quien usa la terminal de quien administra el servidor.
La filosofía Unix en una frase: cada comando hace una cosa bien hecha, y la tubería (
|) lo une todo. La mayor parte de este post trata de eso.
Lo que convierte comandos aislados en una sola herramienta.
Manda la salida de un comando a la entrada del siguiente.
ps aux | grep nginx | wc -l> sobrescribe el archivo; >> añade al final.
comando > saida.txt
comando >> log.txt1 es la salida estándar, 2 es el error.
comando > saida.txt 2> erros.txtEl orden importa: redirige primero el archivo y después une el 2 al 1.
comando > tudo.txt 2>&1
comando &> tudo.txt # atajo de bash/dev/null es el desagüe del sistema.
comando 2>/dev/null
comando >/dev/null 2>&1< alimenta el comando con el contenido del archivo.
sort < nomes.txt
while read linha; do echo "$linha"; done < lista.txtUn bloque de texto directamente en el comando. Muy usado para configuración y SQL.
cat <<EOF > config.yml
servidor: producao
porta: 8080
EOFManda una cadena directamente a la entrada.
grep "erro" <<< "$conteudo"Guarda en un archivo y continúa la tubería. Esencial con sudo.
comando | tee saida.txt
echo "linha" | sudo tee -a /etc/hostsAlgunos comandos no leen de la tubería; xargs lo resuelve.
find . -name "*.log" | xargs rm
cat urls.txt | xargs -n1 curl -sI-P procesa varios a la vez. Una ganancia enorme en una tarea repetitiva.
cat urls.txt | xargs -P 8 -n 1 curl -sO$(...) inserta la salida de un comando dentro de otro.
echo "Hoje é $(date +%F)"
kill $(pgrep -f meu-script)<(...) convierte la salida de un comando en un archivo temporal.
diff <(ls pasta1) <(ls pasta2)
comm -13 <(sort a.txt) <(sort b.txt)Genera listas y secuencias sin bucle.
mkdir -p projeto/{src,test,docs}
touch arquivo{1..5}.txt
cp config.yml{,.bak}Hace cuentas en el propio shell.
echo $((2 + 3 * 4))
total=$((total + 1))Las comillas dobles expanden variables; las simples no expanden nada.
nome="Jhonatan"
echo "Olá $nome" # Olá Jhonatan
echo 'Olá $nome' # Olá $nomeSin comillas, un espacio en el valor se convierte en dos argumentos — el origen de la mitad de los bugs en los scripts.
arquivo="meu arquivo.txt"
rm "$arquivo" # correcto
rm $arquivo # intenta borrar "meu" y "arquivo.txt"$? guarda el resultado del último comando: 0 es éxito.
comando
if [ $? -ne 0 ]; then echo "falhou"; fiSin esto, una tubería solo falla si falla el último comando.
set -o pipefail
falso | true; echo $? # ahora sí reporta el falloSe ejecuta según el éxito del comando anterior.
make build && make deploy
comando || echo "falhou" >&2El trío que procesa texto en cualquier servidor, sin instalar nada.
Patrones en lugar de texto fijo.
grep -E "^[0-9]{3}-[0-9]{4}$" telefones.txtExtrae el fragmento, no la línea entera.
grep -oE "[0-9]{1,3}(\.[0-9]{1,3}){3}" access.log | sort | uniq -c | sort -nrHabilita lookahead, \d, \s y similares.
grep -P "(?<=usuario=)\w+" app.logBusca dentro de un log rotado sin descomprimirlo.
zgrep "erro" /var/log/syslog.2.gz
grep -a "texto" arquivo.binEvita recorrer node_modules y .git.
grep -r "TODO" . --exclude-dir={node_modules,.git,dist}La operación más usada: cambiar texto.
sed 's/antigo/novo/' arquivo.txt # la primera aparición de la línea
sed 's/antigo/novo/g' arquivo.txt # todas-i graba en el propio archivo. Haz siempre una copia con -i.bak.
sed -i.bak 's/porta=8080/porta=9090/' config.iniEvita escapar barras al trabajar con rutas.
sed 's|/var/www|/srv/www|g' config.confRestringe la sustitución a una línea o a un rango.
sed '3s/erro/ok/' arquivo.txt
sed '10,20s/dev/prod/g' arquivo.txtElimina por número, por patrón o las vacías.
sed '5d' arquivo.txt
sed '/^#/d' config.conf # comentarios
sed '/^$/d' arquivo.txt # líneas en blancoAntes (i), después (a) o en su lugar (c).
sed '1i #!/bin/bash' script.sh
sed '/\[servidor\]/a porta=8080' config.ini-n calla la salida por defecto; p imprime lo que interesa.
sed -n '10,20p' arquivo.txt
sed -n '/INICIO/,/FIM/p' log.txtCaptura partes y las reordena.
echo "2026-08-10" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'Sustitución por lotes, combinada con find.
find . -name "*.md" -exec sed -i 's/http:/https:/g' {} +Divide la línea en campos automáticamente.
awk '{print $1, $3}' arquivo.txt
ps aux | awk '{print $2, $11}'-F define el separador de campos.
awk -F: '{print $1}' /etc/passwd
awk -F, '{print $2}' dados.csvSolo procesa las líneas que cumplen la condición.
awk '$3 > 100 {print $1, $3}' vendas.txt
awk '/erro/ {print}' app.logAcumula valores y los imprime al final.
awk '{soma += $2} END {print "Total:", soma}' vendas.txtContador y suma en la misma pasada.
awk '{soma += $1; n++} END {print "Média:", soma/n}' numeros.txtArray asociativo: el "GROUP BY" de la terminal.
awk '{contagem[$1]++} END {for (chave in contagem) print chave, contagem[chave]}' acessos.logNR es el número de línea; NF, la cantidad de campos.
awk 'NR > 1 {print $1}' dados.csv # se salta la cabecera
awk '{print NF}' arquivo.txt # campos por líneaprintf da control total del formato.
awk '{printf "%-20s %8.2f\n", $1, $2}' precos.txtCombina filtros como en SQL.
awk -F, '$3 == "SP" && $4 > 1000 {print $1}' clientes.csvOFS define cómo salen los campos.
awk -F: 'BEGIN {OFS=","} {print $1, $3}' /etc/passwdLa receta clásica: las 10 IPs con más accesos.
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10awk combinado con un filtro de estado.
awk '$9 == 500 {print $7}' access.log | sort | uniq -c | sort -nr | headExtrae la métrica directamente del log.
awk '{soma += $NF; n++} END {printf "média: %.3fs\n", soma/n}' tempos.logcut es más rápido para columnas fijas; awk maneja el espaciado variable.
cut -d, -f1,3 dados.csv # simple y rápido
awk '{print $1, $3}' saida.txt # espaciado irregularUne archivos por columna o por clave, como un JOIN.
paste nomes.txt idades.txt
join -t, -1 1 -2 1 clientes.csv pedidos.csvDeja legible una salida desordenada.
mount | column -t
cat /etc/passwd | column -t -s:Automatizar lo que repites — con el mínimo de trampas.
Primera línea: dice qué intérprete ejecuta el archivo.
#!/usr/bin/env bashSin permiso de ejecución, el script no corre.
chmod +x script.sh
./script.shLas tres líneas que evitan la mayoría de los bugs: sale ante el error, protesta por una variable indefinida y propaga el fallo de la tubería.
set -euo pipefailSin espacios alrededor del =. Comillas al usarlas.
nome="Jhonatan"
echo "Olá, $nome"Sin local, todo es global — y un nombre repetido se convierte en un bug silencioso.
minha_funcao() {
local contador=0
contador=$((contador + 1))
}$1, $2... y $@ para todos.
echo "primeiro: $1"
echo "todos: $@"
echo "quantidade: $#"Usa el valor por defecto cuando la variable está vacía.
porta="${PORTA:-8080}"
destino="${1:?informe o destino}" # aborta con un mensajeCondicional con corchetes dobles (una función de bash, más segura).
if [[ -f config.yml ]]; then
echo "config encontrado"
fiLa cadena completa.
if [[ $1 == "prod" ]]; then
echo "produção"
elif [[ $1 == "hml" ]]; then
echo "homologação"
else
echo "ambiente desconhecido" >&2
exit 1
fiExiste, es un directorio, es legible, tiene contenido.
[[ -e caminho ]] # existe
[[ -f arquivo ]] # es un archivo
[[ -d pasta ]] # es un directorio
[[ -r arquivo ]] # legible
[[ -s arquivo ]] # no está vacíoVacía, igual, distinta, casa con un patrón.
[[ -z "$var" ]] # vacía
[[ -n "$var" ]] # no vacía
[[ "$a" == "$b" ]]
[[ "$arquivo" == *.log ]]La comparación de números usa sus propios operadores.
[[ $n -eq 10 ]] # igual
[[ $n -ne 10 ]] # distinto
[[ $n -gt 10 ]] # mayor
[[ $n -lt 10 ]] # menorMás legible que una pila de elif.
case "$1" in
start) iniciar ;;
stop) parar ;;
restart) parar; iniciar ;;
*) echo "uso: $0 {start|stop|restart}"; exit 1 ;;
esacItera sobre valores literales.
for ambiente in dev hml prod; do
echo "implantando em $ambiente"
doneUsa el glob directamente — nunca la salida de ls.
for arquivo in *.log; do
gzip "$arquivo"
doneUn rango de números con secuencia o al estilo C.
for i in {1..10}; do echo "$i"; done
for ((i = 0; i < 10; i++)); do echo "$i"; doneRepite mientras la condición sea verdadera.
contador=0
while [[ $contador -lt 5 ]]; do
echo "$contador"
contador=$((contador + 1))
doneLa forma correcta de procesar un archivo: IFS= y -r preservan los espacios y las barras.
while IFS= read -r linha; do
echo "Linha: $linha"
done < arquivo.txtLo inverso del while: repite hasta que la condición se vuelva verdadera.
until curl -sf http://localhost:8080/health; do
echo "aguardando o serviço..."
sleep 2
doneSale del bucle o salta a la siguiente iteración.
for i in {1..10}; do
[[ $i -eq 5 ]] && continue
[[ $i -eq 8 ]] && break
echo "$i"
doneAgrupan lógica y reciben argumentos como el script.
saudacao() {
local nome="$1"
echo "Olá, $nome"
}
saudacao "Jhonatan"return devuelve un código de salida; para devolver texto, usa echo y captúralo.
soma() { echo $(( $1 + $2 )); }
resultado=$(soma 2 3)Una lista indexada, con todos los elementos en [@].
servidores=("web1" "web2" "db1")
echo "${servidores[0]}"
echo "${#servidores[@]}" # cantidad
for s in "${servidores[@]}"; do echo "$s"; doneUn mapa clave-valor en bash 4+.
declare -A porta
porta[web]=80
porta[api]=3000
for servico in "${!porta[@]}"; do echo "$servico: ${porta[$servico]}"; doneLongitud, porción y eliminación de prefijo/sufijo, sin llamar a un comando externo.
s="arquivo.tar.gz"
echo "${#s}" # longitud
echo "${s%.gz}" # quita el sufijo
echo "${s#*.}" # quita hasta el primer punto
echo "${s/tar/zip}" # sustituyeGarantiza que el temporal se borre aunque el script muera.
temporario=$(mktemp)
trap 'rm -f "$temporario"' EXIT
# ... usa el archivomktemp los crea con un nombre único y permisos seguros.
arquivo=$(mktemp)
pasta=$(mktemp -d)-p muestra el prompt; -s oculta lo que se escribe.
read -p "Nome: " nome
read -s -p "Senha: " senha; echoLa protección mínima en un script destructivo.
read -p "Apagar tudo? (s/N) " resposta
[[ "$resposta" == "s" ]] || exit 0Parseo de flags al estilo Unix.
while getopts "a:p:v" opcao; do
case $opcao in
a) ambiente="$OPTARG" ;;
p) porta="$OPTARG" ;;
v) verboso=1 ;;
*) exit 1 ;;
esac
doneUna función de log sencilla que salva la depuración más adelante.
log() { echo "[$(date +'%F %T')] $*"; }
log "iniciando implantação"Un mensaje de error no debe ensuciar la salida del script.
echo "erro: arquivo não encontrado" >&2flock impide dos instancias simultáneas — esencial en cron.
flock -n /tmp/meu-script.lock ./meu-script.sh || echo "já está rodando"-x imprime cada comando ejecutado.
bash -x script.sh
set -x # lo activa a mitad del script
set +x # lo desactivaSeñala los errores clásicos antes de que los sufras. Úsalo siempre.
shellcheck script.shCómo un servicio arranca en el boot, se reinicia solo y registra lo que hizo.
Estado actual, PID y las últimas líneas del log.
systemctl status nginxEl trío del día a día.
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginxRelee la configuración manteniendo las conexiones abiertas.
sudo systemctl reload nginx
sudo systemctl reload-or-restart nginxenable solo lo configura; --now además lo inicia ahora.
sudo systemctl enable nginx
sudo systemctl enable --now nginxImpide que arranque en el siguiente boot.
sudo systemctl disable --now nginxDevuelve un código de salida — perfecto para un script.
systemctl is-active nginx
systemctl is-enabled nginxTodo lo que existe, o solo lo que está corriendo.
systemctl list-units --type=service
systemctl list-units --type=service --state=runningLa primera consulta al entrar en un servidor con problemas.
systemctl --failedUn archivo unit mínimo para ejecutar tu aplicación.
# /etc/systemd/system/minha-api.service
[Unit]
Description=Minha API
After=network.target
[Service]
Type=simple
User=app
WorkingDirectory=/opt/minha-api
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.targetObligatorio después de crear o editar cualquier archivo de servicio.
sudo systemctl daemon-reloadCrea un override en lugar de alterar el archivo del paquete.
sudo systemctl edit nginx
sudo systemctl cat nginx # muestra la unit efectivaUn archivo aparte, fuera de git, con las credenciales.
# en la unit:
EnvironmentFile=/etc/minha-api/env
# en el archivo:
DATABASE_URL=postgres://...After los ordena; Requires obliga a que el otro esté activo.
[Unit]
After=postgresql.service
Requires=postgresql.servicesystemd aplica cgroups sin que tengas que configurarlos a mano.
[Service]
MemoryMax=512M
CPUQuota=50%Opciones que reducen mucho el destrozo en caso de intrusión.
[Service]
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/minha-apiImpide que arranque de ninguna forma, ni por dependencia.
sudo systemctl mask apache2
sudo systemctl unmask apache2Modo gráfico, multiusuario o rescate.
systemctl get-default
sudo systemctl set-default multi-user.target
sudo systemctl isolate rescue.targetMuestra quién está retrasando el inicio.
systemd-analyze
systemd-analyze blame | head -20Entiende por qué un servicio arranca antes que otro.
systemctl list-dependencies nginxLa alternativa moderna al cron, con log integrado y control de dependencias.
# /etc/systemd/system/backup.timer
[Unit]
Description=Backup diário
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
# sudo systemctl enable --now backup.timer
# systemctl list-timersTareas que se ejecutan solas — y los detalles que hacen que fallen en silencio.
Abre la programación de tu usuario.
crontab -e
sudo crontab -e -u www-data # la de otro usuarioVer lo que está programado; -r lo borra todo (cuidado).
crontab -l
crontab -rMinuto, hora, día del mes, mes, día de la semana.
# * * * * * comando
# │ │ │ │ └── día de la semana (0-7, 0 y 7 = domingo)
# │ │ │ └──── mes (1-12)
# │ │ └────── día del mes (1-31)
# │ └──────── hora (0-23)
# └────────── minuto (0-59)Las programaciones que cubren casi todo.
0 3 * * * /opt/backup.sh # todos los días a las 3
*/15 * * * * /opt/checa-saude.sh # cada 15 minutos
0 9 * * 1 /opt/relatorio.sh # los lunes a las 9
0 0 1 * * /opt/fechamento.sh # el primer día del mesMás legibles que los cinco campos.
@daily /opt/backup.sh
@hourly /opt/sync.sh
@reboot /opt/inicia.shCron se ejecuta con un entorno mínimo. Usa siempre la ruta absoluta.
# Fallo silencioso:
0 3 * * * backup.sh
# Correcto:
0 3 * * * /usr/local/bin/backup.shSin redirigirla, la salida va al correo local — que nadie lee.
0 3 * * * /opt/backup.sh >> /var/log/backup.log 2>&1Declaradas al principio del archivo, valen para todas las líneas.
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=""Basta con dejar un script ejecutable en esas carpetas.
ls /etc/cron.daily/
ls /etc/cron.d/
cat /etc/crontabUna tarea lenta puede empezar de nuevo antes de terminar. flock lo resuelve.
*/5 * * * * flock -n /tmp/sync.lock /opt/sync.shSe ejecuta una única vez en un momento futuro.
echo "/opt/manutencao.sh" | at 02:00
atq # lista
atrm 3 # eliminaEjecútalo con el mismo entorno del cron para detectar problemas de PATH.
env -i /bin/bash --noprofile --norc -c "/opt/backup.sh"El acceso remoto — y cómo usarlo sin contraseña y sin riesgo.
Usuario, host y puerto.
ssh usuario@servidor
ssh -p 2222 usuario@servidorEd25519 es el estándar actual: más pequeña y más segura que RSA.
ssh-keygen -t ed25519 -C "voce@email.com"Habilita el login sin contraseña.
ssh-copy-id usuario@servidor
ssh-copy-id -i ~/.ssh/id_ed25519.pub usuario@servidorSSH rechaza la clave si los permisos están flojos.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keysAlias que evitan memorizar IP, puerto y usuario.
# ~/.ssh/config
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
# ahora: ssh prodGuarda la clave desbloqueada durante la sesión.
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -lSe ejecuta y vuelve, sin abrir una sesión interactiva.
ssh prod "df -h && uptime"Trae un puerto remoto a tu máquina — la forma segura de acceder a una base de datos.
ssh -L 5432:localhost:5432 prod
# ahora localhost:5432 es el Postgres del servidorExpone un puerto tuyo en el servidor remoto.
ssh -R 8080:localhost:3000 prodNavega como si estuvieras en la red del servidor.
ssh -D 1080 prodAccede a la máquina interna pasando por el host de borde.
ssh -J bastion usuario@servidor-internoEvita la caída por inactividad.
# ~/.ssh/config
Host *
ServerAliveInterval 60
ServerAliveCountMax 3Multiplexing: la segunda conexión al mismo host es instantánea.
Host *
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10mLos tres cambios que más reducen los ataques.
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
Port 2222
sudo systemctl reload sshdValídala antes de recargar — un error aquí te deja fuera.
sudo sshd -t-v muestra cada paso de la autenticación.
ssh -vvv usuario@servidor¿Cambió la clave del servidor? Quita la entrada antigua (y confirma que no sea un ataque).
ssh-keygen -R servidorscp y rsync usan la misma configuración de ~/.ssh/config.
scp arquivo.txt prod:/tmp/
rsync -avz ./site/ prod:/var/www/site/Diagnosticar de verdad la conectividad, los puertos y el tráfico.
Vale hasta el siguiente reinicio — útil en mantenimiento.
sudo ip addr add 192.168.1.50/24 dev eth0
sudo ip link set eth0 upAñade o cambia la puerta de enlace.
sudo ip route add default via 192.168.1.1
ip route get 8.8.8.8 # por dónde sale el tráficoConfiguración persistente moderna.
# /etc/netplan/01-config.yaml
network:
version: 2
ethernets:
eth0:
addresses: [192.168.1.50/24]
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
# sudo netplan applyHabitual en RHEL y en escritorios.
nmcli device status
nmcli connection show
sudo nmcli connection modify eth0 ipv4.addresses 192.168.1.50/24Quién está conectado a qué, ahora mismo.
ss -tan state established
ss -tp # con el procesoDetecta a un cliente abusando o un ataque simple.
ss -tan | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | headVe el paquete de verdad. Insustituible cuando el log no lo explica.
sudo tcpdump -i eth0 port 80 -n
sudo tcpdump -i any host 192.168.1.10 -w captura.pcap-A muestra el contenido ASCII — bueno para HTTP.
sudo tcpdump -i eth0 -A -s0 'tcp port 80 and host api.exemplo.com'Descubre lo que está abierto. Escanea solo lo que es tuyo.
nmap -sT localhost
nmap -p 1-1000 192.168.1.10
nmap -sV 192.168.1.10 # detecta el servicio y la versiónPrueba un puerto, transfiere un archivo y levanta un servidor improvisado.
nc -zv servidor 443
nc -l 9000 # escucha en el puerto
nc servidor 9000 < arquivo.txtMuestra dónde se gasta el tiempo: DNS, conexión, TLS, respuesta.
curl -w "dns:%{time_namelookup} conn:%{time_connect} tls:%{time_appconnect} total:%{time_total}\n" -o /dev/null -s https://exemplo.comValidez, cadena y emisor.
openssl s_client -connect exemplo.com:443 -servername exemplo.com < /dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuerUna capa sencilla sobre iptables, habitual en Ubuntu.
sudo ufw status verbose
sudo ufw allow 22/tcp
sudo ufw allow from 192.168.1.0/24 to any port 5432
sudo ufw enableEl estándar en RHEL y Fedora.
sudo firewall-cmd --list-all
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reloadLo que está realmente aplicado en el kernel.
sudo iptables -L -n -v
sudo nft list ruleset # nftables, el sucesorEn sistemas con systemd-resolved, el /etc/resolv.conf engaña.
resolvectl status
cat /etc/resolv.confDespués de cambiar un registro, la caché local estorba la prueba.
sudo resolvectl flush-cachesiperf3 mide el caudal real del enlace.
# en el servidor
iperf3 -s
# en el cliente
iperf3 -c 192.168.1.10 -t 30Descubre quién está consumiendo la red.
sudo nethogs
sudo iftop -i eth0La dirección física y encender una máquina de forma remota.
ip link show eth0 | grep ether
wakeonlan 00:11:22:33:44:55Del disco en crudo al punto de montaje que sobrevive al reinicio.
Vista de dispositivos, particiones y puntos de montaje.
lsblk -f
sudo fdisk -lInteractivo, para tablas MBR y GPT sencillas.
sudo fdisk /dev/sdb
# n (nueva) · p (primaria) · w (graba)Mejor para un disco mayor de 2 TB (GPT).
sudo parted /dev/sdb mklabel gpt
sudo parted -a opt /dev/sdb mkpart primary ext4 0% 100%Crea el sistema de archivos en la partición.
sudo mkfs.ext4 /dev/sdb1
sudo mkfs.xfs /dev/sdb1Usa el UUID en fstab: el nombre del dispositivo puede cambiar entre arranques.
sudo e2label /dev/sdb1 dados
blkid /dev/sdb1Una entrada en fstab con el UUID y las opciones.
# /etc/fstab
UUID=abcd-1234 /mnt/dados ext4 defaults,noatime 0 2
sudo mount -a # prueba sin reiniciarnoatime reduce la escritura; ro protege; nosuid/nodev/noexec endurecen.
sudo mount -o noatime,nodev,nosuid /dev/sdb1 /mnt/dadosSolo con la partición desmontada.
sudo umount /dev/sdb1
sudo fsck -f /dev/sdb1Amplía el filesystem después de hacer crecer la partición.
sudo resize2fs /dev/sdb1 # ext4
sudo xfs_growfs /mnt/dados # xfs (en caliente)Crea y activa el área de intercambio.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
swapon --showCuánto prefiere el kernel usar la swap. En un servidor de base de datos, valores bajos.
cat /proc/sys/vm/swappiness
sudo sysctl vm.swappiness=10Un volumen lógico permite hacer crecer el disco sin reparticionar.
sudo pvs # volúmenes físicos
sudo vgs # grupos
sudo lvs # volúmenes lógicosDel disco en crudo al volumen montable.
sudo pvcreate /dev/sdb
sudo vgcreate dados-vg /dev/sdb
sudo lvcreate -L 50G -n dados-lv dados-vg
sudo mkfs.ext4 /dev/dados-vg/dados-lvLa gran ventaja: crecer sin downtime.
sudo lvextend -L +20G /dev/dados-vg/dados-lv
sudo resize2fs /dev/dados-vg/dados-lvUna foto del volumen para un backup consistente.
sudo lvcreate -L 5G -s -n snap /dev/dados-vg/dados-lvAccede al contenido sin grabar el medio.
sudo mount -o loop imagem.iso /mnt/isoNFS y SMB/CIFS.
sudo mount -t nfs servidor:/export /mnt/nfs
sudo mount -t cifs //servidor/compartilhado /mnt/win -o username=userAnticipa un fallo de hardware.
sudo smartctl -a /dev/sda
sudo smartctl -t short /dev/sdaDescubre quién está machacando el disco.
sudo iotop -o
pidstat -d 1Latencia y utilización por dispositivo. Un %util cerca de 100 es un cuello de botella.
iostat -xz 1Donde el servidor cuenta lo que pasó.
El log unificado de systemd.
journalctl
journalctl -n 100Filtra por unit — el comando que más vas a usar.
journalctl -u nginx
journalctl -u nginx -f # en vivoRecorta la ventana temporal del incidente.
journalctl --since "2026-08-10 14:00" --until "2026-08-10 15:00"
journalctl --since "1 hour ago"Solo error y superiores.
journalctl -p err
journalctl -p warning..emergEl arranque actual o el anterior — esencial tras una caída.
journalctl -b
journalctl -b -1
journalctl --list-bootsMensajes del kernel, con timestamp legible.
dmesg -T | tail -50
journalctl -kConfirma si el kernel mató tu proceso por falta de memoria.
dmesg -T | grep -i "out of memory"
journalctl -k | grep -i oomFormato JSON para analizarlo en una herramienta externa.
journalctl -u nginx -o json > nginx.json
journalctl -u nginx --since today > nginx.txtCrece hasta el límite configurado — y llena el disco.
journalctl --disk-usage
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=30dDonde escriben los servicios tradicionales.
ls -lh /var/log/
sudo tail -f /var/log/auth.log # autenticación
sudo tail -f /var/log/syslogRota, comprime y descarta el log antiguo — lo que impide que el disco se llene.
cat /etc/logrotate.conf
sudo logrotate -d /etc/logrotate.d/nginx # simula
sudo logrotate -f /etc/logrotate.d/nginx # fuerzaUn archivo propio en /etc/logrotate.d/.
/var/log/minha-api/*.log {
daily
rotate 14
compress
missingok
notifempty
copytruncate
}Hace que tu script aparezca en el log del sistema.
logger -t meu-script "backup concluído"
logger -p user.err -t meu-script "falha ao conectar"grep combinado con contexto y una ventana horaria.
journalctl -u minha-api --since "30 min ago" | grep -i -C 5 "exception"Fallos de autenticación SSH — la primera señal de un ataque.
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | headEndurecer lo básico y automatizar lo que se repite.
Edita siempre con visudo: valida antes de guardar y evita que bloquees el sudo.
sudo visudo
sudo visudo -f /etc/sudoers.d/deployPermite solo lo necesario, en lugar de un acceso irrestricto.
# /etc/sudoers.d/deploy
deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart minha-apiBloquea una IP tras varios intentos de login fallidos.
sudo apt install fail2ban
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 192.168.1.10Deja que el servidor aplique una corrección crítica por su cuenta.
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgradesUna auditoría sencilla: ¿lo que está escuchando debería estar escuchando?
sudo ss -tulpn | grep LISTENInvestigación posterior al incidente.
sudo find /etc -mtime -2 -type f
sudo find / -mmin -60 -type f -not -path "/proc/*" 2>/dev/nullDetecta un binario del sistema modificado.
sudo debsums -c # Debian/Ubuntu
sudo rpm -Va # RHEL/FedoraAuditoría — y el recordatorio de que el tuyo también queda registrado.
sudo cat /home/usuario/.bash_historyGPG para proteger un backup o un archivo sensible.
gpg -c segredo.txt # cifra con contraseña
gpg -d segredo.txt.gpg > segredo.txtSin depender de un sitio de terceros.
openssl rand -base64 32
head -c 32 /dev/urandom | base64