Módulo 4: Permisos, procesos y entorno
1. Introducción: quién eres, qué corre y qué sabe tu shell
Descripción
Al terminar esta lección vas a poder mirar cualquier mensaje de error que te devuelva la terminal —Permission denied, command not found, o un puerto que dice estar ocupado— y saber, antes de tocar una sola tecla, a cuál de tres familias de problema pertenece: permisos, procesos o entorno. Todavía no vas a resolver los tres a fondo —eso son las siete lecciones que siguen—, pero vas a dejar de adivinar.
Esto importa porque esos tres mensajes concentran una cantidad enorme de las horas que un desarrollador junior pierde en su primer año, y casi nadie te explica por qué pasan. Imagina tu primer día en un trabajo nuevo: heredas la laptop de alguien que se fue de la empresa, clonas el repositorio del equipo y corres el script que en el README promete dejarte todo funcionando. La terminal te devuelve tres palabras —Permission denied— y ahí se te complica la mañana. La reacción más común, la que casi todos aprendemos por imitación y no por explicación, es probar con fuerza bruta: sudo delante de cualquier cosa que falle, chmod 777 sobre cualquier archivo que se queje, reiniciar la computadora cuando ya no se te ocurre nada más. A veces funciona. Nunca te dice por qué funcionó, y ese "por qué" es exactamente lo que este módulo te devuelve.
Conexión con el módulo: esta lección abre el módulo 4 con el mapa completo —las tres familias de problema, por qué la fuerza bruta parece funcionar y qué significa diagnosticar en su lugar— y anuncia el proyecto que cierra el módulo. La siguiente lección, Usuarios, grupos y por qué existen los permisos, baja de este mapa al primer terreno concreto: el modelo de usuarios de Unix y por qué tu propia laptop se comporta como si fuera un servidor compartido.
El médico de guardia, no el remedio casero
Toda persona que empieza a usar la terminal hereda, tarde o temprano, tres remedios caseros que nadie le explicó de fondo: poner sudo delante de cualquier comando que falle, poner chmod 777 sobre cualquier archivo que se queje, y reiniciar la computadora cuando ya no se te ocurre nada más. Son remedios caseros en el sentido estricto de la palabra: no nacen de entender la causa, nacen de haber visto que el síntoma desapareció una vez después de aplicarlos. A veces funcionan —por casualidad, o por pura fuerza bruta— y ese éxito ocasional es justo lo que los mantiene vivos generación tras generación de desarrolladores.
Compáralo con un médico de guardia de verdad. No le receta amoxicilina a cualquier persona que entra con dolor, sin importar si el dolor es una infección, una alergia o un hueso roto: primero pregunta qué duele, desde cuándo y qué lo empeora. Recién con esa información decide el tratamiento —y a veces el tratamiento correcto es no hacer nada todavía—. Este módulo te entrena para hacer exactamente eso frente a una terminal, organizando cada síntoma posible en tres carpetas de historia clínica:
- Permisos — quién tiene permitido leer, escribir o ejecutar cada archivo, y por qué eso es una decisión y no un accidente.
- Procesos — qué programas están corriendo en tu máquina en este momento, quién es su dueño, y cómo se termina uno con precisión en vez de a ciegas.
- Entorno — qué sabe tu shell sobre dónde buscar los comandos que escribes, y qué variables lleva consigo mientras trabaja.
Cada una de las tres tiene su propio capítulo más adelante en este módulo. Por ahora, lo único que necesitas es la carpeta correcta: saber en cuál de las tres vive el síntoma que tienes enfrente, antes de intentar ninguna cura.
Ejemplo trabajado
Vamos a reproducir, con comandos reales, los tres síntomas que le dan nombre a este módulo. No vas a arreglar ninguno todavía —eso es exactamente lo que no vamos a hacer en esta lección—, solo vas a aprender a reconocer a qué familia pertenece cada uno.
Síntoma 1 — intentas ejecutar tu propio script:
echo 'echo "deploy complete"' > setup.sh
./setup.sh
Qué esperar (bash):
bash: ./setup.sh: Permission denied
Si tu shell es zsh (el que trae macOS por defecto desde 2019), el mismo problema se reporta distinto: zsh: permission denied: ./setup.sh. El mensaje cambia de forma según el shell; la causa que estudias en la lección 3 es la misma.
Síntoma 2 — intentas correr una herramienta que el proyecto espera que ya tengas instalada:
lint-project
Qué esperar (bash):
bash: lint-project: command not found
Qué esperar (zsh):
zsh: command not found: lint-project
Síntoma 3 — intentas levantar un servidor de prueba mientras ya tienes otro corriendo. Abre dos pestañas de terminal. En la primera, deja corriendo:
python3 -m http.server 8000
Sin cerrar esa pestaña, en la segunda corre exactamente el mismo comando:
python3 -m http.server 8000
Qué esperar en la segunda pestaña (la traza completa es más larga; aquí solo importa la última línea):
Traceback (most recent call last):
...
OSError: [Errno 48] Address already in use
En Linux vas a ver [Errno 98] en vez de [Errno 48] — es el mismo problema, con el número de error que usa cada sistema operativo.
Ahora clasifica los tres, con la sola información que tienes hoy, sin decodificar nada todavía:
| Síntoma | Familia | Por qué |
|---|---|---|
Permission denied al ejecutar ./setup.sh | Permisos | El archivo existe y lo puedes leer, pero el sistema no te dejó ejecutarlo: es una pregunta sobre quién puede hacer qué con ese archivo. |
command not found al correr lint-project | Entorno | El shell no encontró ningún programa con ese nombre en los lugares donde sabe buscar. No es que el archivo exista y esté prohibido: es que tu shell no lo ubica. |
OSError: Address already in use al levantar el segundo servidor | Procesos | Algo que ya está corriendo en tu máquina tiene ocupado ese número de puerto. El problema no es el archivo ni el shell: es un programa vivo que hay que identificar. |
Esa tabla es, literalmente, el mapa del módulo. Cada fila tiene una lección —o varias— dedicada por completo a resolverla con precisión.
Por qué el remedio casero "funciona" (y por qué te cobra después)
Vale la pena entender por qué la fuerza bruta parece funcionar, porque eso es lo que la hace tan difícil de abandonar.
sudo delante de cualquier cosa le dice al sistema "ejecuta esto como si fueras el usuario con más poder que existe en esta máquina, sin verificar los permisos normales". Por eso "funciona": no resuelve el desajuste de permisos, lo evita por completo, pasando por encima de todo el sistema de permisos. El precio llega después. El caso documentado con más frecuencia es sudo npm install -g algo: instala el paquete, sí, pero deja carpetas del gestor de paquetes con dueño root en vez de con tu usuario normal. La próxima vez que instales algo sin sudo —que es como se supone que debe usarse— te encuentras con un EACCES nuevo, en un lugar donde antes no había ninguno. La documentación oficial de npm dedica una página entera a este problema exacto y recomienda no usar sudo para instalar paquetes, precisamente por esta razón.
chmod 777 sobre cualquier archivo que se queje le da permiso de lectura, escritura y ejecución a cualquier persona con una cuenta en esa máquina, no solo a ti. En tu laptop personal el riesgo es bajo. En un servidor compartido —donde vas a trabajar tarde o temprano— es abrir una puerta sin cerradura en un edificio con más de un inquilino. La lección 3 te muestra exactamente cuánto permiso necesitas dar, ni un bit más.
Reiniciar la computadora a veces sí resuelve algo: un proceso realmente atascado puede desaparecer con el reinicio. Pero no te dice cuál proceso era ni por qué apareció, así que si algo lo vuelve a dejar corriendo mañana, vas a reiniciar otra vez sin haber aprendido nada. La lección 5 te da el comando exacto para encontrar y terminar un proceso específico, sin apagar los otros cincuenta que sí necesitas.
Ninguno de los tres remedios está prohibido en sí mismo —hay momentos legítimos para usar sudo, y hasta para reiniciar—. Son un problema como primer reflejo, antes de saber qué familia de problema tienes enfrente. Ese orden —diagnosticar primero, actuar después— es la habilidad completa de este módulo.
El proyecto del módulo: la clínica de un entorno roto
Los siete capítulos que siguen terminan en un proyecto que le da nombre a esta metáfora: vas a recibir un entorno de trabajo deliberadamente roto —un script sin permiso de ejecución, un proceso fantasma ocupando un puerto que necesitas, un comando que "debería" estar disponible y no aparece— y tu tarea no es arreglarlo con lo primero que se te ocurra. Es escribir, síntoma por síntoma, tu propia historia clínica: qué observaste, a qué familia pertenece, qué comando usaste para confirmarlo y, recién entonces, la corrección exacta y mínima. Nada de sudo a ciegas ni de chmod 777 de repuesto.
Errores comunes
Creer que Permission denied es un error del sistema o de la terminal portándose mal (conceptual). Qué pasa: alguien ve el mensaje y lo interpreta como una falla —"la terminal está rota", "este archivo está corrupto"— en vez de como información. Por qué ocurre: en casi cualquier otro software, un mensaje en rojo significa que algo salió mal. En Unix, Permission denied casi siempre significa que el sistema hizo exactamente su trabajo: revisó quién eres, revisó qué le pediste hacer, y te lo negó a propósito. Cómo detectarlo: si tu primera reacción frente al mensaje es buscar cómo "arreglar la terminal" en vez de preguntarte qué permiso te falta, ya caíste en esta confusión. Cómo corregirlo: trata cada Permission denied como una pregunta bien formulada por el sistema —¿de verdad quieres que esto sea posible?— y no como un obstáculo a esquivar. Las próximas dos lecciones te dan el vocabulario exacto para responderla.
Usar sudo como respuesta automática a cualquier error, sin leer qué dice el mensaje. Qué pasa: un comando falla, y la reacción es anteponer sudo sin haber verificado si el mensaje siquiera menciona permisos. Por qué ocurre: sudo "funciona" con una frecuencia sorprendente porque muchos errores no relacionados con permisos —una dependencia faltante, un puerto ocupado, una ruta mal escrita— casualmente también desaparecen si ejecutas como superusuario, aunque sea por una razón completamente distinta a la que creíste. Cómo detectarlo: si no puedes explicar en una frase por qué el problema era de permisos específicamente, sudo no fue un diagnóstico: fue una apuesta que salió bien. Cómo corregirlo: lee el mensaje de error completo antes de decidir nada; la lección 4 te enseña a distinguir cuándo sudo es de verdad la solución y cuándo es la señal de que el error real es otro.
Reiniciar la computadora frente a un proceso que no responde, en vez de identificarlo. Qué pasa: algo se traba —un puerto ocupado, un programa colgado— y la solución de siempre es reiniciar todo el sistema. Por qué ocurre: reiniciar sí termina el proceso problemático, junto con todos los demás que tenías abiertos, así que parece una solución completa cuando en realidad es una que no distingue nada. Cómo detectarlo: si el mismo síntoma —el mismo puerto ocupado, el mismo programa colgado— te vuelve a pasar semanas después y sigues sin saber qué programa lo causaba, nunca lo diagnosticaste: solo lo pospusiste. Cómo corregirlo: la lección 5 te da el comando exacto para ver qué proceso ocupa un recurso específico y terminar solo ese, dejando todo lo demás intacto.
Ejercicios
1. Sin ejecutar nada todavía, clasifica cada síntoma en una de las tres familias —permisos, procesos o entorno—, usando solo el criterio de esta lección (qué pregunta responde cada familia): (a) corres deploy.sh y la terminal responde Permission denied; (b) intentas iniciar tu aplicación y ves Address already in use; (c) escribes terraform en una máquina nueva y la terminal responde command not found; (d) intentas borrar un archivo de un compañero y el sistema te lo impide; (e) tu servidor de pruebas no arranca porque "ya hay algo escuchando" en ese puerto.
Ver solución
(a) Permisos: el archivo existe; lo que falta es autorización para ejecutarlo. (b) Procesos: hay un programa vivo ocupando un recurso (el puerto) que tu nuevo proceso necesita. (c) Entorno: el shell no encontró ningún programa con ese nombre en los lugares donde sabe buscar; puede que ni siquiera esté instalado, o que esté en un lugar que tu shell no conoce todavía. (d) Permisos: es la misma pregunta que el primer caso —quién puede hacer qué con un archivo— aplicada a borrar en vez de a ejecutar. (e) Procesos: es el mismo síntoma que el segundo caso, dicho con otras palabras. Esto funciona porque cada familia responde una pregunta distinta —¿quién puede? (permisos), ¿qué está corriendo? (procesos), ¿dónde busca el shell? (entorno)— y basta con identificar cuál pregunta encaja con el síntoma para clasificarlo, sin necesitar todavía el comando que lo resuelve.
2. Un compañero de equipo instala una librería con sudo npm install -g algo. Le funciona ese mismo día. Tres semanas después, sin usar sudo, un npm install -g distinto le falla con EACCES. Explica, con tus propias palabras, la cadena completa: por qué el primer comando "funcionó" y por qué el segundo, sin relación aparente, falló.
Ver solución
sudo npm install -g algo corrió como superusuario, así que cuando npm creó o modificó carpetas dentro de su directorio de instalación global, esas carpetas quedaron con dueño root en vez de con el usuario normal. Ese día no hubo ningún síntoma visible: el paquete se instaló y punto. Tres semanas después, un npm install -g corrido sin sudo —la forma correcta de usarlo— intenta escribir en esas mismas carpetas, y como ahora pertenecen a root, el usuario normal no tiene permiso: de ahí el EACCES. El problema no apareció de la nada; se sembró tres semanas antes, en el instante en que se usó sudo la primera vez. Esto funciona porque conecta el error de hoy con su causa real —un cambio de propietario silencioso, no un fallo del gestor de paquetes— que es exactamente el mecanismo que esta lección describe para sudo.
3. Ves este mensaje en tu terminal, en una máquina que acabas de heredar de un compañero: zsh: permission denied: ./run-tests.sh. Sin ejecutar chmod de ningún tipo todavía: ¿a qué familia pertenece?, ¿qué es lo primero que no deberías hacer?, y ¿qué necesitas confirmar antes de corregirlo, aunque todavía no sepas el comando exacto?
Ver solución
Pertenece a la familia de permisos: el shell encontró el archivo (si no existiera, el error sería no such file or directory, no permission denied), pero no te deja ejecutarlo. Lo primero que no deberías hacer es chmod 777 run-tests.sh: resuelve el síntoma dándole permiso de ejecución a cualquier persona con cuenta en esa máquina, más de lo que hace falta. Antes de corregirlo con precisión —eso es exactamente la lección 3— conviene confirmar quién es el dueño actual del archivo y qué permiso mínimo (probablemente solo ejecución para el dueño) resuelve el problema sin abrir más de lo necesario. Esto funciona porque el mensaje mismo distingue "no existe" de "existe pero no autorizado" —son dos errores distintos con dos textos distintos— y esa distinción es la que separa un problema de entorno de uno de permisos.
4. Marca cada afirmación como verdadera o falsa y corrige las falsas en una frase: (a) Permission denied significa que el archivo no existe; (b) command not found y Permission denied son la misma familia de problema; (c) sudo puede hacer "desaparecer" un error que no tenía nada que ver con permisos; (d) reiniciar la computadora identifica cuál proceso estaba ocupando un puerto.
Ver solución
(a) Falsa: si el archivo no existiera, el mensaje sería otro (algo como no such file or directory); Permission denied significa que el archivo existe pero no tienes autorización para la acción que pediste. (b) Falsa: command not found es un problema de entorno (el shell no ubicó el programa); Permission denied es un problema de permisos (el sistema sí encontró el archivo, pero no autorizó la acción). (c) Verdadera: sudo evita por completo la verificación normal de permisos, así que errores que no eran de permisos a veces desaparecen igual, por una razón distinta a la que uno cree. (d) Falsa: reiniciar termina el proceso —junto con todos los demás— pero no te dice cuál era ni por qué apareció; no diagnostica nada. Esto funciona porque cada corrección obliga a distinguir el mensaje exacto que el sistema muestra en cada caso, que es la única pista disponible antes de aprender los comandos de diagnóstico de las próximas lecciones.
Resumen y siguiente paso
Ya tienes el mapa completo del módulo: tres familias de problema —permisos, procesos, entorno—, cada una con su propia pregunta (¿quién puede?, ¿qué está corriendo?, ¿dónde busca el shell?), y un criterio para reconocer cuál es cuál con solo leer el mensaje de error. También sabes por qué sudo a ciegas, chmod 777 de repuesto y reiniciar sin diagnosticar parecen funcionar, y por qué ese éxito ocasional es justo lo que los hace peligrosos como primer reflejo.
Antes de avanzar deberías poder: clasificar un mensaje de error nuevo —uno que no viste en esta lección— en una de las tres familias, solo leyendo su texto; explicar, con el ejemplo de sudo npm install -g, por qué un remedio casero puede sembrar un problema que aparece semanas después; y nombrar en una frase qué construye el proyecto de este módulo y por qué se llama "clínica".
Esta lección te dio el mapa; todavía no te dio un solo comando de diagnóstico real. Eso empieza en la siguiente lección, donde vas a conocer el modelo de usuarios de Unix —por qué tu laptop, aunque la uses solo tú, se comporta como si fuera un servidor con inquilinos— y vas a entender, antes de tocar un solo permiso, por qué existe algo que un permiso tiene que proteger.
Recursos
- A Short Introduction to Sudo — documentación oficial del proyecto sudo: qué problema resuelve y qué política de seguridad implementa.
- Resolving EACCES permissions errors when installing packages globally — la página oficial de npm que documenta el problema exacto del Ejercicio 2 y por qué recomienda no usar
sudopara instalar paquetes. - Command Search and Execution — Bash Reference Manual — referencia oficial de GNU sobre cómo bash busca un comando antes de reportar
command not found; la vas a necesitar completa en la lección 6. - errno — Standard errno system symbols — documentación oficial de Python sobre los códigos de error del sistema operativo, incluido
EADDRINUSE(48 en macOS, 98 en Linux) que viste en el Síntoma 3. - Change the default shell in Terminal on Mac — Apple Support — referencia oficial de Apple sobre zsh como shell por defecto, relevante para las diferencias de mensajes que viste en esta lección.