Si un programa no encuentra una herramienta, utiliza un idioma inesperado o sólo funciona desde una terminal concreta, puede que la diferencia esté en las variables de entorno. No son una lista única para todo Linux. Cada proceso recibe unos valores y puede transmitirlos a los programas que inicia.
Desde la terminal podemos consultar esos valores, preparar uno para una sola orden o exportarlo para los procesos que abramos desde esa sesión. La parte importante es distinguir una variable de la shell de una que realmente llega al programa.
Vamos a comprobarlo con nombres de prueba, sin modificar PATH, HOME ni archivos de configuración del usuario para seguir los ejemplos.
Consultar una variable sin mostrar todo el entorno
Para consultar el idioma que recibe un programa podemos ejecutar:
printenv LANG
El nombre se pasa sin el signo $. printenv busca esa variable dentro del entorno que ha recibido y muestra su valor si existe. Para consultar varias:
printenv LANG LC_ALL
Es posible que una esté definida y otra no. No debemos interpretar una salida vacía como una avería automática: depende de qué variable consultamos y de si existe o tiene un valor vacío.
La documentación de printenv explica su funcionamiento y sus códigos de salida. Si no encuentra una de las variables solicitadas, devuelve un estado distinto de cero.
También podemos ejecutar printenv sin argumentos para listar el entorno completo. Antes de copiar esa salida en un foro, revisamos si contiene claves, tokens, direcciones internas o datos de una aplicación. Para resolver un problema suele ser suficiente consultar los nombres que intervienen.

Variables de una sesión mostradas por printenv. Conviene revisar el contenido antes de compartir una salida completa.
Una variable de Bash no siempre está en el entorno
Abrimos una shell de prueba para no mezclar las siguientes comprobaciones con la sesión donde estamos trabajando:
bash --noprofile --norc
No carga los perfiles ni el archivo de inicio habitual de Bash, pero sigue heredando el entorno del proceso que la ha abierto. No es un entorno vacío ni un aislamiento de seguridad.
Creamos una variable ficticia y consultamos su valor desde esa shell:
ESL_EJEMPLO='dos palabras'
printf '%s\n' "$ESL_EJEMPLO"
Veremos dos palabras. Ahora intentamos consultarla como variable de entorno:
printenv ESL_EJEMPLO
Si hemos creado este nombre por primera vez y no estaba exportado, printenv no lo encuentra. La variable existe en Bash, pero no se ha incluido en el entorno que recibe ese programa externo.
Esto también explica por qué algunas opciones de Bash no aparecen en printenv. Por ejemplo, HISTSIZE sirve para configurar la shell, pero no se convierte automáticamente en una variable exportada por el hecho de tener un valor.
Usar export para los programas que iniciamos después
Marcamos la variable de ejemplo para que la reciban los procesos hijos:
export ESL_EJEMPLO
printenv ESL_EJEMPLO
Ahora la consulta muestra su valor. Podemos hacer la asignación y la exportación juntas:
export ESL_EJEMPLO='valor exportado'
Si abrimos un nuevo proceso Bash desde esa sesión, también recibe el valor:
bash --noprofile --norc -c 'printf "%s\n" "$ESL_EJEMPLO"'
La explicación del entorno en Bash describe esta herencia. No estamos cambiando una tabla global que se actualice dentro de todas las aplicaciones abiertas.
Un editor que ya estaba funcionando puede conservar el entorno con el que se inició. Y otra terminal abierta desde el escritorio puede proceder de un proceso distinto, no de la shell en la que acabamos de ejecutar export.
Por eso una variable que funciona en una sesión y no en otra no se arregla necesariamente copiando su valor una y otra vez. Hay que saber desde dónde se inicia el programa que la necesita.
Definir un valor sólo para una orden
Si queremos probar un ajuste sin exportarlo para el resto de la sesión, podemos anteponer la asignación a una orden externa:
ESL_EJEMPLO='sólo para esta orden' printenv ESL_EJEMPLO
Ese proceso recibe el valor temporal. Cuando termina, la variable que tenía nuestra shell mantiene su valor anterior, si existía. Podemos comprobarlo con:
printf '%s\n' "$ESL_EJEMPLO"
En este ejemplo seguimos usando un nombre ficticio. Es más seguro aprender el mecanismo así que cambiar una variable de configuración importante y descubrir después que otra herramienta depende de ella.
Este comportamiento está explicado para la llamada a un programa externo. Funciones y ciertas órdenes internas de la shell pueden tener detalles distintos, así que no utilizaría el ejemplo como una regla sin excepciones para cualquier construcción de Bash.
Diferenciar nombre, expansión y comillas
Estas dos órdenes hacen cosas distintas:
printenv HOME
printf '%s\n' "$HOME"
En la primera, printenv recibe el nombre HOME y busca su valor en el entorno. En la segunda, Bash expande $HOME antes de ejecutar printf.
Las comillas mantienen el valor como un único argumento, aunque contenga espacios. No pasamos printenv $HOME para consultar la variable: estaríamos entregándole el contenido de la ruta como si fuera un nombre.

Consulta de la ruta personal desde la terminal.
Esta distinción aparece también en scripts que reciben nombres de archivo. Entrecomillar un valor no es sólo una preferencia de estilo. Cambia cómo se construyen los argumentos que recibe la orden.
Quitar la variable o dejar de exportarla
Dentro de nuestra shell de prueba podemos retirar la marca de exportación:
export -n ESL_EJEMPLO
printf '%s\n' "$ESL_EJEMPLO"
printenv ESL_EJEMPLO
El valor sigue estando disponible para Bash, pero los nuevos procesos ya no lo reciben como variable exportada. Si queremos eliminarlo también de esta shell:
unset ESL_EJEMPLO
No hemos modificado los procesos que ya estaban abiertos. Un hijo que recibió el valor antes puede seguir conservándolo. Del mismo modo, si un proceso hijo cambia su propio entorno, no cambia por esa vía el de su padre.
Para salir de la shell de prueba y volver a la anterior:
exit
Estos cambios eran de esa sesión. No hemos editado ningún archivo para hacerlos persistentes.
Hacerlo persistente sólo cuando sepamos dónde se necesita
No existe un archivo de inicio que sirva igual para todos los casos. Una terminal interactiva, una sesión de inicio, una aplicación del escritorio y un servicio pueden recibir su configuración por caminos diferentes.
En Bash, ~/.bashrc es habitual para shells interactivas que no son de inicio de sesión. Las shells de login utilizan otros archivos según las reglas de inicio de Bash. Añadir una línea a uno de ellos no significa que un servicio o todas las ventanas del escritorio vayan a leerla.
Antes de guardar una asignación permanente, haría copia del archivo correspondiente, comprobaría qué shell utilizamos y probaría en una sesión nueva. No duplicaría la misma línea en varios perfiles hasta que algo empiece a funcionar.
Si el ajuste pertenece a un servicio, revisamos su mecanismo de configuración, no lo trasladamos automáticamente al perfil personal. Y si contiene un secreto, necesitamos un lugar y unos permisos adecuados, no un archivo que terminemos subiendo con el proyecto.
Si un programa recibe un valor distinto del esperado
Primero consultamos la variable concreta desde el contexto donde iniciamos el programa. Después comprobamos si estaba exportada y si esa aplicación se abrió antes del cambio. Reiniciar el ordenador no debería ser el primer paso para entender una diferencia entre procesos.
También miramos si el programa utiliza realmente esa variable o dispone de una opción propia que tenga prioridad. Tener un valor en printenv no obliga a una aplicación a interpretarlo de la manera que esperamos.
Para pedir ayuda, guardamos el nombre, una versión del valor sin información sensible, la orden utilizada y cómo se inicia el programa. Un volcado completo del entorno suele añadir ruido y puede revelar datos que no eran necesarios.
Con una consulta concreta y una prueba temporal podemos entender la mayoría de estos casos sin ir modificando perfiles a ciegas. Lo útil es seguir el recorrido del valor: dónde se define, a qué proceso llega y qué programa lo utiliza.
