En realidad, no sabía que hay dos tipos diferentes de variables a las que puedo acceder desde la línea de comandos. Todo lo que sabía es que puedo declarar variables como:
foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"
o accediendo a ellos con un signo $, como:
echo $foo
echo ${bar[1]}
o usando variables incorporadas, como:
echo $PWD
PATH=$PATH:"/usr/bin/myProg"
Ahora, escucho que hay dos (¿al menos?) Tipos de variables: variables de shell y variables de entorno.
- ¿Cuál es el propósito de tener dos tipos diferentes?
- ¿Cómo sé de qué tipo es una variable?
- ¿Cuáles son los usos típicos de cada uno?
shell
command-line
environment-variables
Sharkant
fuente
fuente

Respuestas:
Las variables de entorno son una lista de
name=valuepares que existen independientemente del programa (shell, aplicación, daemon ...). Por lo general, los procesos secundarios los heredan (creados por una secuenciafork/exec): los procesos secundarios obtienen su propia copia de las variables principales.Las variables de shell existen solo en el contexto de un shell. Solo se heredan en subshells (es decir, cuando el shell se bifurca sin una
execoperación). Dependiendo de las características del shell, las variables pueden no solo ser cadenas simples como las del entorno, sino también matrices, variables compuestas, escritas como enteros o de coma flotante, etc.Cuando se inicia un shell, todas las variables de entorno que hereda de su padre se convierten también en variables de shell (a menos que no sean válidas como variables de shell y otros casos de esquina como los
IFSque se reinician con algunos shells), pero estas variables heredadas se etiquetan como exportadas 1 . Eso significa que permanecerán disponibles para procesos secundarios con el valor potencialmente actualizado establecido por el shell. Ese es también el caso con las variables creadas bajo el shell y etiquetadas como exportadas con laexportpalabra clave.La matriz y otras variables de tipo complejo no se pueden exportar a menos que su nombre y valor se puedan convertir al
name=valuepatrón, o cuando exista un mecanismo específico de shell (por ejemplo:bashexporta funciones en el entorno y algunos shells exóticos, no POSIX, comorcyespueden exportar matrices )Entonces, la principal diferencia entre las variables de entorno y las variables de shell es su alcance: las variables de entorno son globales, mientras que las variables de shell no exportadas son locales para el script.
Tenga en cuenta también que los shells modernos (al menos
kshybash) admiten un tercer alcance de variables de shell. Las variables creadas en funciones con latypesetpalabra clave son locales para esa función (la forma en que se declara la función habilita / deshabilita esta característicaksh, y el comportamiento de persistencia es diferente entrebashyksh). Ver /unix//a/28349/25941 Esto se aplica a los depósitos modernos como
ksh,dash,bashy similares. El shell Bourne heredado y los shells de sintaxis no Bournecshtienen comportamientos diferentes.fuente
execve()llamada del sistema, por lo que se usan (generalmente) para persistir los datos durante la ejecución de otros comandos (en el mismo proceso).IFSen algunos shells).rc,espueden exportar matrices usando una codificación adhoc.bashyrctambién puede exportar funciones usando variables de entorno (nuevamente, usando una codificación especial).ksh93,typesetrestringe el alcance solo en funciones declaradas con lafunction foo { ...; }sintaxis, no con lafoo() cmdsintaxis Bourne ( ) (y su alcance estático no es dinámico como en otros shells).Variables de Shell
Las variables de shell son variables cuyo alcance se encuentra en la sesión de shell actual, por ejemplo, en una sesión de shell interactiva o un script.
Puede crear una variable de shell asignando un valor a un nombre no utilizado:
El uso de variables de shell es hacer un seguimiento de los datos en la sesión actual. Las variables de shell generalmente tienen nombres con letras minúsculas.
Variables de entorno
Una variable de entorno es una variable de shell que se ha exportado. Esto significa que será visible como una variable, no solo en la sesión de shell que lo creó, sino también para cualquier proceso (no solo shells) que se inicie desde esa sesión.
o
Una vez que se ha exportado una variable de shell, permanece exportada hasta que se desarma, o hasta que su "propiedad de exportación" se elimina (con
export -ninbash), por lo que generalmente no es necesario volver a exportarla. Desarmar una variable conunsetelimina (no importa si es una variable de entorno o no).Las matrices y los hashes asociativos en
bashy otros shells no se pueden exportar para convertirse en variables de entorno. Las variables de entorno deben ser variables simples cuyos valores son cadenas, y a menudo tienen nombres que consisten en letras mayúsculas.El uso de variables de entorno es para realizar un seguimiento de los datos en la sesión de shell actual, pero también para permitir que cualquier proceso iniciado tome parte de esos datos. El caso típico de esto es la
PATHvariable de entorno, que puede establecerse en el shell y luego ser utilizada por cualquier programa que desee iniciar programas sin especificar una ruta completa a ellos.La colección de variables de entorno en un proceso a menudo se denomina "el entorno del proceso". Cada proceso tiene su propio entorno.
Las variables de entorno solo se pueden "reenviar", es decir, un proceso hijo nunca puede cambiar las variables de entorno en su proceso padre, y aparte de configurar el entorno para un proceso hijo al iniciarlo, un proceso padre no puede cambiar el entorno existente de un proceso hijo
Las variables de entorno se pueden enumerar con
env(sin ningún argumento). Aparte de eso, aparecen igual que las variables de shell no exportadas en una sesión de shell. Esto es un poco especial para el shell ya que la mayoría de los otros lenguajes de programación no suelen mezclar variables "ordinarias" con variables de entorno (ver más abajo).envtambién se puede usar para establecer los valores de una o varias variables de entorno en el entorno de un proceso sin establecerlas en la sesión actual:Esto comienza
makecon la variable de entornoCCestablecida en el valorclangyCXXestablecida enclang++.También se puede usar para limpiar el entorno de un proceso:
Este se inicia
bashpero no transfiere el entorno actual al nuevobashproceso (que todavía se tienen las variables de entorno, ya que crea otros nuevos desde sus secuencias de comandos shell de inicialización).Ejemplo de diferencia
Otros idiomas
Hay funciones de biblioteca en la mayoría de los lenguajes de programación que permiten obtener y configurar las variables de entorno. Tenga en cuenta que, dado que las variables de entorno se almacenan como una simple relación clave-valor, generalmente no son "variables" del lenguaje. Un programa puede obtener el valor (que siempre es una cadena de caracteres) correspondiente a una clave (el nombre de la variable de entorno), pero luego tendrá que convertirlo a un entero o cualquier tipo de datos que el lenguaje espera que tenga el valor.
En C, las variables de entorno pueden ser accedidas usando
getenv(),setenv(),putenv()yunsetenv(). Las variables creadas con estas rutinas se heredan de la misma manera por cualquier proceso que inicie el programa C.Otros lenguajes pueden tener estructuras de datos especiales para lograr lo mismo, como el
%ENVhash en Perl o laENVIRONmatriz asociativa en la mayoría de las implementaciones deawk.fuente
getenv(),setenv(),putenv()yunsetenv(). Las variables creadas con estas rutinas se heredan de la misma manera por cualquier proceso que inicie el programa C. Otros idiomas pueden tener estructuras de datos especiales para la misma cosa, como%ENVen Perl.exec*()familia de funciones también puede establecer el entorno para el proceso que se ejecuta.Las variables de shell son difíciles de duplicar.
Sin embargo, las variables de entorno pueden duplicarse; son solo una lista, y una lista puede tener entradas duplicadas. Aquí hay
envdup.cque hacer eso.Que podemos compilar y ejecutar diciéndole
envdupque luego ejecuteenvpara mostrarnos qué variables de entorno están configuradas ...Esto quizás solo sea útil para encontrar errores u otras rarezas en la forma en que se manejan los programas
**environ.Parece que Python 3.6 aquí pasa ciegamente los duplicados (una abstracción permeable) mientras que Perl 5.24 no. ¿Qué hay de las conchas?
Gosh, ¿qué sucede si
sudosolo desinfecta la primera entrada del entorno pero luego sebashejecuta con la segunda? HolaPATHoLD_RUN_PATHexplotar. ¿Está tusudo(y todo lo demás ) parcheado para ese agujero ? Las vulnerabilidades de seguridad no son "una diferencia anecdótica" ni simplemente "un error" en el programa de llamadas.fuente
Una variable de entorno es como una variable de shell , pero no es específica del shell . Todos los procesos en sistemas Unix tienen almacenamiento variable de entorno . La principal diferencia entre las variables de entorno y de shell es: que el sistema operativo pasa todas las variables de entorno de su shell a los programas que ejecuta el shell, mientras que no se puede acceder a las variables de shell en los comandos que ejecuta.
env –El comando le permite ejecutar otro programa en un entorno personalizado sin modificar el actual. Cuando se usa sin argumento, imprimirá una lista de las variables de entorno actuales.printenv –El comando imprime todas o las variables de entorno especificadas.set –El comando establece o desactiva las variables de shell. Cuando se usa sin argumento, imprimirá una lista de todas las variables, incluidas las variables de entorno y de shell, y las funciones de shell.unset –El comando elimina las variables de shell y de entorno.export –El comando establece variables de entornofuente