El Sistema de Archivos /proc en Profundidad
El sistema de archivos /proc es un sistema de archivos virtual del kernel Linux que expone información del sistema y de los procesos en ejecución como archivos y directorios. No ocupa espacio real en disco—sus contenidos se generan dinámicamente por el kernel—y sirve como interfaz principal para monitorear el sistema, ajustar parámetros del kernel en tiempo real con sysctl, y diagnosticar problemas de rendimiento y hardware. Esta guía explora en profundidad la estructura y uso de /proc para administración y optimización de sistemas Linux.
Requisitos Previos
- Cualquier distribución Linux con kernel 3.x o superior
- Acceso al sistema (algunos archivos requieren root)
- Conocimientos básicos de la línea de comandos
Estructura de /proc
# Ver la estructura principal de /proc
ls /proc/
# Directorios numerados = información de procesos por PID
ls /proc/ | grep '^[0-9]' | head -10
# Archivos y directorios principales:
# /proc/cpuinfo - Información del CPU
# /proc/meminfo - Información de memoria
# /proc/net/ - Estadísticas de red
# /proc/sys/ - Parámetros del kernel (modificables)
# /proc/filesystems - Sistemas de archivos soportados
# /proc/mounts - Sistemas de archivos montados
# /proc/uptime - Tiempo de actividad del sistema
# /proc/loadavg - Carga promedio del sistema
# /proc/version - Versión del kernel
# /proc/cmdline - Parámetros del kernel al arrancar
Información de Procesos
Cada proceso en ejecución tiene un directorio /proc/PID/ con su información:
# Ver el PID de un proceso
pidof nginx
PID=$(pidof -s nginx) # Solo el primer PID
# Estructura de /proc/PID/
ls /proc/$PID/
# cmdline - Línea de comandos completa con argumentos
# cwd - Directorio de trabajo actual (enlace simbólico)
# environ - Variables de entorno
# exe - Enlace al ejecutable
# fd/ - Descriptores de archivo abiertos
# fdinfo/ - Información detallada de descriptores
# maps - Mapas de memoria
# mem - Memoria del proceso
# net/ - Estadísticas de red del proceso
# oom_adj - Ajuste OOM killer
# oom_score - Puntuación actual del OOM killer
# smaps - Mapas de memoria detallados
# stat - Estado del proceso (para programas)
# status - Estado legible del proceso
# wchan - Función del kernel donde está esperando
# Ver la línea de comando de un proceso
cat /proc/$PID/cmdline | tr '\0' ' '
# O con xargs
tr '\0' ' ' < /proc/$PID/cmdline
# Ver directorio de trabajo actual de un proceso
readlink /proc/$PID/cwd
# Ver el ejecutable de un proceso
readlink /proc/$PID/exe
# Ver archivos abiertos por un proceso
ls -la /proc/$PID/fd/
# Equivalente a: lsof -p $PID
Estado y Estadísticas de Procesos
# Ver estado legible del proceso
cat /proc/$PID/status
# Información clave en /proc/PID/status:
# Name: nombre del proceso
# State: S (sleeping), R (running), D (disk sleep), Z (zombie), T (stopped)
# VmRSS: memoria RAM usada (Resident Set Size)
# VmSize: memoria virtual total
# Threads: número de hilos
# Uid: UID real, efectivo, guardado
# Ver estadísticas detalladas del proceso
cat /proc/$PID/stat
# 44 campos separados por espacios con toda la info del proceso
# Uso de memoria detallado por región
cat /proc/$PID/smaps | head -30
# Calcular uso total de memoria de un proceso desde smaps
awk '/^Rss:/{sum+=$2} END{print "RSS total:", sum, "kB"}' /proc/$PID/smaps
Monitorear Todos los Procesos
# Script para monitorear uso de recursos de todos los procesos
cat > /usr/local/bin/proc-monitor.sh << 'EOF'
#!/bin/bash
# Monitoreo de procesos usando /proc
echo "=== Monitor de Procesos via /proc ==="
printf "%-8s %-20s %-10s %-10s %s\n" "PID" "NOMBRE" "RSS(MB)" "ESTADO" "CMD"
for dir in /proc/[0-9]*/; do
PID=$(basename "$dir")
[ -f "$dir/status" ] || continue
NOMBRE=$(awk '/^Name:/{print $2}' "$dir/status" 2>/dev/null)
ESTADO=$(awk '/^State:/{print $2}' "$dir/status" 2>/dev/null)
RSS=$(awk '/^VmRSS:/{printf "%.1f", $2/1024}' "$dir/status" 2>/dev/null)
CMD=$(tr '\0' ' ' < "$dir/cmdline" 2>/dev/null | cut -c1-50)
[ -n "$NOMBRE" ] && [ -n "$RSS" ] && \
printf "%-8s %-20s %-10s %-10s %s\n" "$PID" "$NOMBRE" "${RSS:-0}" "$ESTADO" "$CMD"
done | sort -k3 -rn | head -20
EOF
chmod +x /usr/local/bin/proc-monitor.sh
Información del Sistema y Hardware
CPU
# Información detallada del CPU
cat /proc/cpuinfo
# Extraer información específica
grep "model name" /proc/cpuinfo | head -1 # Modelo del CPU
grep -c "processor" /proc/cpuinfo # Número de CPUs/núcleos lógicos
grep "cpu MHz" /proc/cpuinfo # Frecuencia actual de cada núcleo
# Estadísticas de uso del CPU por tiempo
cat /proc/stat | grep "^cpu"
# Formato: cpu user nice system idle iowait irq softirq steal guest guest_nice
# Calcular uso de CPU en tiempo real (diferencia entre dos lecturas)
read CPU1 < <(awk '/^cpu /{print $2+$3+$4+$5+$6+$7+$8; exit}' /proc/stat)
read IDLE1 < <(awk '/^cpu /{print $5; exit}' /proc/stat)
sleep 1
read CPU2 < <(awk '/^cpu /{print $2+$3+$4+$5+$6+$7+$8; exit}' /proc/stat)
read IDLE2 < <(awk '/^cpu /{print $5; exit}' /proc/stat)
echo "CPU uso: $(( (CPU2-CPU1-IDLE2+IDLE1) * 100 / (CPU2-CPU1) ))%"
Memoria
# Información de memoria completa
cat /proc/meminfo
# Extraer información clave
awk '/MemTotal/{total=$2} /MemFree/{free=$2} /MemAvailable/{avail=$2} /Cached:/{cached=$2}
END{printf "Total: %.1f GB\nLibre: %.1f GB\nDisponible: %.1f GB\nCaché: %.1f GB\n",
total/1024/1024, free/1024/1024, avail/1024/1024, cached/1024/1024}' /proc/meminfo
# Información de swap
grep -E "SwapTotal|SwapFree|SwapCached" /proc/meminfo
# Ver páginas de memoria hugepages
grep -i huge /proc/meminfo
# Información de NUMA (si el sistema tiene múltiples sockets)
cat /proc/zoneinfo | head -50
Información del Sistema
# Tiempo de actividad del sistema
cat /proc/uptime
# Formato: segundos_activo segundos_idle_total
# Convertir a formato legible
awk '{d=int($1/86400); h=int(($1%86400)/3600); m=int(($1%3600)/60);
printf "Uptime: %d días %d horas %d minutos\n", d, h, m}' /proc/uptime
# Carga promedio del sistema
cat /proc/loadavg
# Formato: 1min 5min 15min procesos_ejecutando/total_procesos último_pid_creado
# Información del kernel
cat /proc/version
cat /proc/sys/kernel/ostype
cat /proc/sys/kernel/osrelease
cat /proc/sys/kernel/hostname
# Número máximo de procesos
cat /proc/sys/kernel/pid_max
# Dispositivos de hardware
cat /proc/devices # Dispositivos de bloque y carácter registrados
cat /proc/bus/pci/devices # Dispositivos PCI
Parámetros del Kernel con sysctl
/proc/sys/ expone parámetros del kernel modificables en tiempo real:
# Ver todos los parámetros del kernel
sysctl -a 2>/dev/null | head -30
# O directamente en /proc/sys/
ls /proc/sys/
# kernel/ - Parámetros del kernel
# net/ - Parámetros de red
# vm/ - Parámetros de memoria virtual
# fs/ - Parámetros del sistema de archivos
# Leer un parámetro
cat /proc/sys/kernel/hostname
sysctl kernel.hostname
# Modificar un parámetro (temporal, hasta reinicio)
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1
# Parámetros de rendimiento comunes
cat /proc/sys/vm/swappiness # Agresividad del uso de swap (0-100)
cat /proc/sys/vm/dirty_ratio # % memoria sucia antes de forzar escritura
cat /proc/sys/fs/file-max # Máximo de archivos abiertos en el sistema
# Optimizaciones típicas de red para servidores
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
sysctl -w net.core.netdev_max_backlog=5000
# Hacer permanentes los cambios
cat >> /etc/sysctl.d/99-optimizaciones.conf << 'EOF'
# Optimizaciones de red para servidor web
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 5000
# Reutilizar puertos en TIME_WAIT más agresivamente
net.ipv4.tcp_tw_reuse = 1
# Reducir memoria de buffer de envío/recepción mínima
net.ipv4.tcp_rmem = 4096 65536 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
EOF
sysctl -p /etc/sysctl.d/99-optimizaciones.conf
Estadísticas de Red
# Estadísticas de interfaces de red
cat /proc/net/dev
# Bytes, paquetes, errores y drops por interfaz
# Estadísticas TCP
cat /proc/net/tcp # Conexiones TCP IPv4 en hex
cat /proc/net/tcp6 # Conexiones TCP IPv6
# Ver conexiones TCP en formato legible (equivalente a ss/netstat)
awk 'NR>1{
# Convertir hex a IP:Puerto
split($2, local, ":");
split($3, remote, ":");
printf "Local: %d.%d.%d.%d:%d\n",
strtonum("0x"substr(local[1],7,2)),
strtonum("0x"substr(local[1],5,2)),
strtonum("0x"substr(local[1],3,2)),
strtonum("0x"substr(local[1],1,2)),
strtonum("0x"local[2])
}' /proc/net/tcp | head -10
# Estadísticas detalladas del protocolo TCP
cat /proc/net/snmp | grep -A2 "^Tcp:"
# Estadísticas de UDP
cat /proc/net/udp
# Tabla de ruteo
cat /proc/net/route
# Tabla ARP
cat /proc/net/arp
# Estadísticas de netfilter (iptables)
cat /proc/net/nf_conntrack | wc -l # Número de conexiones trackeadas
cat /proc/sys/net/netfilter/nf_conntrack_count # Conexiones actuales
cat /proc/sys/net/netfilter/nf_conntrack_max # Límite máximo
Monitoreo de Rendimiento
Script de Dashboard de /proc
cat > /usr/local/bin/proc-dashboard.sh << 'EOF'
#!/bin/bash
# Dashboard de rendimiento usando solo /proc
while true; do
clear
echo "=== Dashboard del Sistema via /proc - $(date) ==="
# Uptime
echo ""
awk '{d=int($1/86400); h=int(($1%86400)/3600); m=int(($1%3600)/60);
printf "Uptime: %d días %02d:%02d horas\n", d, h, m}' /proc/uptime
# Carga del sistema
echo ""
echo "=== Carga del Sistema ==="
read L1 L5 L15 RUNNING TOTAL LASTPID < /proc/loadavg
printf "Carga: %.2f (1m) %.2f (5m) %.2f (15m) | Procesos: %s/%s\n" \
$L1 $L5 $L15 $RUNNING $TOTAL
# Memoria
echo ""
echo "=== Memoria ==="
awk '/MemTotal/{t=$2} /MemAvailable/{a=$2} /SwapTotal/{st=$2} /SwapFree/{sf=$2}
END{
printf "RAM: %.1f/%.1f GB (%.0f%% libre)\n", (t-a)/1048576, t/1048576, a/t*100;
if(st>0) printf "Swap: %.1f/%.1f GB\n", (st-sf)/1048576, st/1048576;
}' /proc/meminfo
# CPU (lectura simple de /proc/stat)
echo ""
echo "=== CPU ==="
awk '/^cpu /{idle1=$5; total1=$2+$3+$4+$5+$6+$7+$8}' /proc/stat
sleep 0.5
awk '/^cpu /{idle2=$5; total2=$2+$3+$4+$5+$6+$7+$8}
END{printf "CPU uso: %.1f%%\n", (1-(idle2-idle1)/(total2-total1))*100}' \
<(cat /proc/stat) /proc/stat 2>/dev/null
# Red
echo ""
echo "=== Red (bytes/s) ==="
awk 'NR>2{gsub(/:/, " "); printf "%-12s RX:%s TX:%s\n",$1,$2,$10}' /proc/net/dev | \
grep -v "lo"
sleep 5
done
EOF
chmod +x /usr/local/bin/proc-dashboard.sh
Configuración del Sistema en Tiempo Real
# Ajustar swappiness para servidores de base de datos (valor bajo = menos swap)
echo 10 > /proc/sys/vm/swappiness
# Aumentar el límite de archivos abiertos
echo 1000000 > /proc/sys/fs/file-max
# Deshabilitar el tiempo de acceso en i-nodes para reducir escrituras
# (configurar en /etc/fstab con opción 'noatime')
# Ajustar el OOM killer para un proceso específico (más negativo = menos probable matar)
PID=$(pidof mi-proceso-critico)
echo -17 > /proc/$PID/oom_adj # -17 = nunca matar (obsoleto)
echo -1000 > /proc/$PID/oom_score_adj # Interfaz moderna (-1000 = nunca matar)
# Ver puntuación actual del OOM killer para un proceso
cat /proc/$PID/oom_score
# Forzar liberación de caché de páginas
# 1=pagecache, 2=dentries+inodes, 3=todo
echo 1 > /proc/sys/vm/drop_caches
Solución de Problemas
No se puede leer un archivo en /proc/PID/:
# Muchos archivos requieren root
sudo cat /proc/1/environ
# Los archivos de /proc de otros usuarios requieren permisos elevados
sudo cat /proc/$PID/maps
"Too many open files" en una aplicación:
# Ver el límite actual del sistema
cat /proc/sys/fs/file-max
# Ver archivos abiertos actualmente
cat /proc/sys/fs/file-nr
# Formato: abiertos en uso / 0 / máximo
# Ver límite del proceso específico
cat /proc/$PID/limits | grep "open files"
# Aumentar para la sesión actual
ulimit -n 65535
/proc/net/conntrack lleno (error de seguimiento de conexiones):
# Ver límite actual
cat /proc/sys/net/netfilter/nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count
# Aumentar el límite
echo 262144 > /proc/sys/net/netfilter/nf_conntrack_max
# Permanente
echo "net.netfilter.nf_conntrack_max = 262144" >> /etc/sysctl.conf
Conclusión
El sistema de archivos /proc es una ventana directa al interior del kernel Linux, proporcionando acceso a información de procesos, estadísticas de hardware, parámetros de red y configuración del sistema en tiempo real. Comprender su estructura permite realizar diagnósticos profundos sin herramientas adicionales y ajustar el comportamiento del kernel para optimizar el rendimiento según las necesidades específicas de cada carga de trabajo. Muchas herramientas de monitoreo como top, free, netstat y ps leen directamente de /proc, por lo que dominar esta interfaz proporciona capacidades de diagnóstico equivalentes pero con mayor control y flexibilidad.


