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=value
pares 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
exec
operació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
IFS
que 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 laexport
palabra 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=value
patrón, o cuando exista un mecanismo específico de shell (por ejemplo:bash
exporta funciones en el entorno y algunos shells exóticos, no POSIX, comorc
yes
pueden 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
ksh
ybash
) admiten un tercer alcance de variables de shell. Las variables creadas en funciones con latypeset
palabra 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 entrebash
yksh
). Ver /unix//a/28349/25941 Esto se aplica a los depósitos modernos como
ksh
,dash
,bash
y similares. El shell Bourne heredado y los shells de sintaxis no Bournecsh
tienen 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).IFS
en algunos shells).rc
,es
pueden exportar matrices usando una codificación adhoc.bash
yrc
también puede exportar funciones usando variables de entorno (nuevamente, usando una codificación especial).ksh93
,typeset
restringe el alcance solo en funciones declaradas con lafunction foo { ...; }
sintaxis, no con lafoo() cmd
sintaxis 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 -n
inbash
), por lo que generalmente no es necesario volver a exportarla. Desarmar una variable conunset
elimina (no importa si es una variable de entorno o no).Las matrices y los hashes asociativos en
bash
y 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
PATH
variable 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).env
tambié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
make
con la variable de entornoCC
establecida en el valorclang
yCXX
establecida enclang++
.También se puede usar para limpiar el entorno de un proceso:
Este se inicia
bash
pero no transfiere el entorno actual al nuevobash
proceso (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
%ENV
hash en Perl o laENVIRON
matriz 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%ENV
en 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.c
que hacer eso.Que podemos compilar y ejecutar diciéndole
envdup
que luego ejecuteenv
para 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
sudo
solo desinfecta la primera entrada del entorno pero luego sebash
ejecuta con la segunda? HolaPATH
oLD_RUN_PATH
explotar. ¿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