Sé que Bash y Zsh son compatibles con local
variables, pero hay sistemas que solo tienen shells compatibles con POSIX. Y local
no está definido en los shells POSIX.
Entonces quiero preguntar qué shells admiten local
palabra clave para definir variables locales?
Editar :Acerca de los caparazones me refiero al predeterminado /bin/sh
caparazón.
Respuesta aceptada:
No es tan simple como admitir local
o no. Hay mucha variación en la sintaxis y cómo se hace entre shells que tienen una forma u otra de ámbito local.
Por eso es muy difícil llegar a un estándar que esté de acuerdo con todos. Consulte http://austingroupbugs.net/bug_view_page.php?bug_id=767 para ver el esfuerzo de POSIX en ese frente.
el alcance local se agregó primero en ksh a principios de los años 80.
La sintaxis para declarar una variable local en una función fue con typeset
:
function f {
typeset var=value
set -o noglob # also local to the function
...
}
(El soporte de funciones se agregó al shell de Bourne más tarde, pero con una sintaxis diferente (comando f() command
) y ksh
Se agregó soporte para ese también más adelante; el shell Bourne nunca tuvo alcance local (excepto, por supuesto, a través de subshells))
El local
El AFAIK incorporado se agregó primero al shell de Almquist (usado en BSD, dash, busybox sh) en 1989, pero funciona de manera significativamente diferente a ksh
typeset
. ash
los derivados no son compatibles con typeset
como un alias para local
, pero siempre puedes definir uno a mano.
bash y zsh agregaron typeset
alias de local
en 1989 y 1991 respectivamente.
ksh88 agregó local
como un alias no documentado para typeset
alrededor de 1990 y pdksh y sus derivados en 1994. posh
(basado en pdksh
) eliminó typeset
(para el estricto cumplimiento de la política de Debian que requiere local
, pero no typeset
).
POSIX inicialmente se opuso a especificar typeset
sobre la base de que era dinámico alcance Entonces ksh93 (una reescritura de ksh en 1993 por David Korn) cambió a static alcance en su lugar. También en ksh93, a diferencia de ksh88, el alcance local solo se realiza para las funciones declaradas con ksh
sintaxis (function f {...}
), no la sintaxis de Bourne (f() {...}
) y el local
se eliminó el alias.
Sin embargo, el ksh93v-beta y la versión final de AT&T se pueden compilar con un modo "bash" experimental (en realidad habilitado de forma predeterminada) que realiza un alcance dinámico (en formas molestas de funciones, incluso con local
y typeset
) cuando ksh93
se invoca como bash
. local
difiere de typeset
en ese caso, en que solo se puede invocar desde dentro de una función. Ese bash
el modo se desactivará de forma predeterminada en ksh2020 a través del local
/declare
alias para typeset
se retendrá incluso cuando el modo bash no esté compilado (aunque aún con alcance estático).
yash
(escrito mucho más tarde), tiene typeset
(a la ksh88), pero solo ha tenido local
como un alias desde la versión 2.48 (diciembre de 2018).
@Schily mantiene un descendiente de shell Bourne que recientemente se ha hecho mayormente compatible con POSIX, llamado bosh
que admite alcance local desde la versión 2016-07-06 (con local
, similar a ash
).
Entonces, los shells tipo Bourne que tienen algún tipo de alcance local para las variables hoy en día son:
- ksh, todas las implementaciones y sus derivados (ksh88, ksh93, pdksh y derivados como posh, mksh, OpenBSD sh).
- ash y todos sus derivados (NetBSD sh, FreeBSD sh, dash, busybox sh)
- golpe
- zsh
- yash
- tonterías
Hasta el sh
de diferentes sistemas van, tenga en cuenta que hay sistemas donde el POSIX sh
está en /bin
(la mayoría), y otros donde no lo es (como Solaris donde está en /usr/xpg4/bin
). Para el sh
implementación en varios sistemas que tenemos:
- ksh88:la mayoría de Unices comerciales derivados de SysV (AIX, HP/UX, Solaris¹…)
- bash:la mayoría de los sistemas GNU/Linux, Cygwin, macOS
- ash:de forma predeterminada en Debian y la mayoría de los derivados (incluidos Ubuntu, Linux/Mint), aunque el administrador puede cambiarlo a bash o mksh. NetBSD, FreeBSD y algunos de sus derivados (no macOS).
- busybox sh:muchos, si no la mayoría, de los sistemas Linux integrados
- pdksh o derivados:OpenBSD, MirOS
Ahora, donde difieren:
typeset
(ksh, pdksh, bash, zsh, yash) frente alocal
(ksh88, pdksh, bash, zsh, ash, yash 2.48+).- estática (ksh93, en
function f {...}
función), frente al alcance dinámico (todos los demás shells). Por ejemplo, sifunction f { typeset v=1; g; echo "$v"; }; function g { v=2; }; f
salidas1
o2
. Vea también cómoexport
el atributo afecta el alcance enksh93
. - si
local
/typeset
simplemente hace que la variable sea local (ash
,bosh
), o crea una nueva instancia de la variable (otros shells). Por ejemplo, siv=1; f() { local v; echo "${v:-empty}"; }; f
salidas1
oempty
(ver también ellocalvar_inherit
opción en bash 5.0 y superior). - con los que crean una nueva variable, si la nueva hereda los atributos (como
export
) y/o tipo y cuáles de la variable en el ámbito principal. Por ejemplo, siexport V=1; f() { local V=2; printenv V; }; f
imprime1
,2
o nada. - si esa nueva variable tiene un valor inicial (vacío, 0, lista vacía, según el tipo,
zsh
) o está inicialmente desarmado. - si
unset V
en una variable en un ámbito local deja la variableunset
, o simplemente peladuras un nivel de alcance (mksh
,yash
,bash
en algunas circunstancias). Por ejemplo, siv=1; f() { local v=2; unset v; echo "$v"; }
salidas1
o nada (ver también ellocalvar_unset
opción en bash 5.0 y superior) - me gusta para
export
, si es una palabra clave o solo una mera función integrada o ambas y bajo qué condiciones se considera una palabra clave. - me gusta para
export
, si los argumentos se analizan como argumentos de comando normales o como asignaciones (y bajo qué condiciones). - si puede declarar local una variable que era de solo lectura en el ámbito principal.
- las interacciones con
v=value myfunction
dondemyfunction
mismo declarav
como local o no.
Esos son los que estoy pensando en este momento. Consulte el error del grupo austin anterior para obtener más detalles.
En cuanto al alcance local para las opciones de shell (a diferencia de variables ), los shells que lo soportan son:
ksh88
(con la sintaxis de definición de ambas funciones):hecho de manera predeterminada, no conozco ninguna forma de deshabilitarlo.ash
(desde 1989):conlocal -
. Hace el$-
parámetro (que almacena la lista de opciones) local.ksh93
:ahora solo se hace parafunction f {...}
funciones.zsh
(desde 1995). Consetopt localoptions
. También conemulate -L
para que el modo de emulación (y su conjunto de opciones) sea local para la función.bash
(desde 2016) conlocal -
como enash
.
Relacionado:¿Md5sum comando binario y modo de texto?