Variables de entorno vs Parámetros posicionales
Antes de comenzar a analizar el $INTEGERtipo de variables, debemos comprender cuáles son realmente y cómo difieren de las variables de entorno. Variables como $INTEGERlas denominadas parámetros posicionales. Esto se describe en el estándar POSIX (Interfaz del sistema operativo portátil), sección 2.1 (énfasis mío):
- El shell ejecuta una función (vea Comando de definición de función), incorporado (vea Utilidades incorporadas especiales), archivo ejecutable o script, dando los nombres de los argumentos como parámetros posicionales numerados del 1 al n, y el nombre del comando (o en el caso de una función dentro de una secuencia de comandos, el nombre del script) como el parámetro posicional el número 0 (ver comando Buscar y Ejecución).
Por el contrario, variables como $HOMEy $PATHson variables de entorno. Su definición se describe en la sección 8 de la norma. :
Las variables de entorno definidas en este capítulo afectan al funcionamiento de múltiples utilidades, funciones y aplicaciones. Hay otras variables de entorno que son de interés sólo para los servicios públicos específicos. Las variables de entorno que se aplican a una única utilidad sólo se definen como parte de la descripción de utilidad.
Observe su descripción. Los parámetros posicionales están destinados a aparecer en frente de un comando, es decir command positional_arg_1 positional_arg_2.... Ellos están destinados a ser proporcionada por el usuario para contar lo que específicamente comando a hacer. Cuando lo haga echo 'Hello' 'World', imprimirá las cadenas Helloy World, porque estos son parámetros posicionales para echolas cosas sobre las que desea echooperar. Y echoestá construido de tal manera que entiende los parámetros posicionales como cadenas para imprimir (a menos que sean uno de los indicadores opcionales como -n). Si lo hace con diferentes comandos que podría no entender qué HelloyWorldes porque tal vez espera un número. Observe que los parámetros posicionales no se "heredan": un proceso secundario no conoce los parámetros posicionales del padre a menos que se pase explícitamente al proceso secundario. A menudo se ve parámetros posicionales que se pasa con los scripts de envoltura - los que tal vez comprueban por ejemplo ya existente de un comando o añadir parámetros de posición adicionales para el comando real que se llama.
Por el contrario, las variables de entorno están destinadas a afectar múltiples programas. Son entorno de variables, porque están fuera del conjunto del programa en sí (más sobre esto más adelante). Ciertas variables de entorno como HOMEo PATHtienen formato específico, significado específico, y significarán lo mismo para cada programa. HOMEvariable significa igual a cualquiera de utilidad externa como /usr/bin/findo su shell (y por consiguiente a una secuencia de comandos) - es el directorio inicial del nombre de usuario bajo el que se ejecuta el proceso. Tenga en cuenta que las variables ambientales se pueden utilizar para dar cuenta de la conducta comando específico, por ejemplo,UIDLa variable de entorno se puede utilizar para verificar si el script se ejecuta con privilegios de root o no y se ramifica a acciones específicas en consecuencia. Las variables de entorno son heredables - procesos hijos reciben copia del entorno de los padres. Véase también Si los procesos heredan el entorno del padre, ¿por qué necesitamos exportar?
En resumen, la principal distinción es que las variables de entorno se establecen fuera del comando y no están destinadas a ser variadas (generalmente), mientras que los parámetros posicionales son cosas que el comando debe procesar y cambiar.
No solo conceptos de shell
Lo que me he dado cuenta de los comentarios es que se está mezclando terminal y concha, y que se lo recomendaría leer acerca de los terminales reales que en otro tiempo eran dispositivos físicos. Hoy en día, el "terminal" al que normalmente nos referimos, esa ventana con fondo negro y texto verde es en realidad software, un proceso. Terminal es un programa que se ejecuta una concha, mientras que la cáscara es también un programa, sino el que lee lo que se escribe en la ejecución (es decir, si se trata de shell interactivo; conchas no interactivas son secuencias de comandos y sh -c 'echo foo'tipos de invocaciones). Más sobre cáscaras de aquí .
Esta es una distinción importante, pero también es importante reconocer que el terminal es un programa y, por lo tanto, se adhiere a las mismas reglas de entorno y parámetros posicionales. Tu gnome-terminalcuando se inicia se verá en su SHELLvariable de entorno, y generar el shell por defecto apropiado para usted, a menos que se especifique algún otro comando con -e. Digamos que cambié mi shell predeterminado a ksh - gnome-terminal se generará en kshlugar de bash. Ese también es un ejemplo de cómo los programas usan el entorno. Si se lo digo de forma explícita gnome-terminalcon el -ecorrer cáscara específica - lo hará, pero no va a ser permanente. Por el contrario, el medio ambiente está mayormente inalterado (más sobre eso más adelante).
Como puede ver, las variables de entorno y de posición son propiedades de un proceso / comando, no solo shell. Cuando se trata de scripts de shell, también siguen el modelo establecido por el lenguaje de programación C. Tomemos por ejemplo el C mainfunción que normalmente se ve como
int main(int argc, char **argv)
, Donde argces el número de argumentos de línea de comandos y argves efectivamente matriz de parámetros de línea de comandos, y luego está environla función (en Linux que de man -e 7 environ) a las cosas de acceso como la ruta del directorio principal del usuario, lista de directorios en PATHdonde podemos buscar los ejecutables, etc. scripts de shell también se modelan de forma similar. En terminología de shell, tenemos parámetros posicionales $1, $2y así sucesivamente, mientras que $#es el número de parámetros posicionales. ¿Qué hay de $0? Ese es el nombre del ejecutable en sí, que también está modelado a partir del lenguaje de programación C: argv[0]sería el nombre de su C "ejecutable". Y esto es bastante cierto para la mayoría de lenguajes de programación y script .
conchas interactiva vs no interactivas
Una de las cosas que ya he insinuado es la distinción entre shells interactivos y no interactivos . El mensaje donde escribe los comandos: es interactivo, interactúa con el usuario. Por el contrario, cuando usted tiene un script de shell o ejecutar bash -c''eso es no interactivo.
Y aquí es donde la distinción se vuelve importante. La cáscara que ya ejecuta un proceso, que se generó con los parámetros de posición (por bashshell de entrada es una "... cuyo primer carácter del argumento es un cero -., O uno iniciado con la opción --login" ( referencia ) )
Por el contrario, las secuencias de comandos y proyectiles lanzados con -copción puede aprovechar $1y $2argumentos. Por ejemplo,
$ bash -c 'echo $1; stat $2' sh 'Hello World' /etc/passwd
Hello World
File: '/etc/passwd'
Size: 2913 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 6035604 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017-08-12 14:48:37.125879962 -0600
Modify: 2017-08-12 14:48:37.125879962 -0600
Change: 2017-08-12 14:48:37.137879811 -0600
Birth: -
Tenga en cuenta que también lo he usado shallí, porque una pequeña peculiaridad de la -copción es tomar el primer parámetro posicional y asignarlo, a $0diferencia de ser un nombre del programa.
Otra cosa que es importante tener en cuenta es que los parámetros posicionales son lo que yo llamo "framable". Observe cómo, primero lanzamos bashcon sus propios parámetros posicionales, pero esos parámetros posicionales se convirtieron en parámetros para echoy stat. Y cada programa lo entiende a su manera. Si le damos a statuna cadena Hello Worldy no hay archivo Hello World, produciría un error; bashlo trata simplemente como una cadena simple, pero statespera que cadena a un nombre de archivo existente. Por el contrario, todos los programas estarían de acuerdo en que la variable de entorno HOMEes un directorio (a menos que el programador lo codifique de manera no razonable).
¿Podemos jugar con las variables de entorno y los parámetros posicionales?
Técnicamente, podemos perder el tiempo con ambos, pero no debemos perder el tiempo con las variables de entorno, mientras que a menudo tenemos que proporcionar parámetros posicionales. Podemos ejecutar comandos de shell con anteponiendo una variable, por ejemplo:
$ hello=world bash -c 'echo $hello'
world
También podemos colocar variables en el entorno simplemente usando export variable=valuedesde shell o script. O podemos ejecutar un comando con un entorno completamente vacío con env -c command arg1 arg2. Sin embargo, generalmente no se recomienda jugar con el entorno, especialmente usando variables en mayúsculas o sobrescribiendo variables de entorno ya existentes. Tenga en cuenta que se recomienda aunque no es una norma.
Para los parámetros posicionales, la manera de ponerlos es obvio, sólo les anteponer al comando, sino que también hay formas de establecer ellos de otra forma , así como el cambio de la lista de los parámetros a través shiftde comandos.
En conclusión, el propósito de estos dos es diferente, y que existe por una razón. Espero personas obtuvieron una idea de esta respuesta, y fue muy divertido leyendo casi como lo fue para mí escribir esta respuesta.
Nota sobre el mandato set
El setcomando, de acuerdo con el manual, se comporta así (del manual bash, énfasis agregado):
Sin opciones, el nombre y el valor de cada variable de shell se muestran en un formato que se puede reutilizar como entrada para establecer o restablecer las variables establecidas actualmente.
En otras palabras setmira a variables específicas a Shell, algunos de los cuales resultan ser en el entorno, por ejemplo HOME. Por órdenes de contraste como envy printenvvistazo a la variable de entorno real con la que se ejecuta un comando. Ver también esto .
export 3convertirse$3en una variable de entorno. No puedesunset 3; y no puede asignar$3un nuevo valor usando3=val.