Vím, že Bash a Zsh podporují local proměnné, ale existují systémy, které mají pouze shelly kompatibilní s POSIX. A local je v POSIX shellech nedefinovaný.
Chci se tedy zeptat, které shelly podporují local klíčové slovo pro definování lokálních proměnných?
Upravit :O shellech mám na mysli výchozí /bin/sh shell.
Přijatá odpověď:
Není to tak jednoduché jako podpora local nebo ne. Existuje mnoho variací v syntaxi a v tom, jak se to dělá mezi shelly, které mají jednu nebo druhou formu místního rozsahu.
Proto je velmi těžké přijít s normou, která bude souhlasit se všemi. Podívejte se na http://austingroupbugs.net/bug_view_page.php?bug_id=767, kde najdete úsilí POSIX v této oblasti.
místní rozsah byl přidán jako první v ksh na počátku 80. let.
Syntaxe pro deklaraci lokální proměnné ve funkci byla s typeset :
function f {
typeset var=value
set -o noglob # also local to the function
...
}
(podpora funkcí byla do Bourne shellu přidána později, ale s jinou syntaxí (příkaz f() command ) a ksh později také přidána podpora pro tento; Bourne shell nikdy neměl lokální rozsah (samozřejmě kromě přes subshells))
local vestavěný AFAIK byl poprvé přidán do shellu Almquist (používaný v BSD, dash, busybox sh) v roce 1989, ale funguje výrazně odlišně od ksh typeset . ash deriváty nepodporují typeset jako alias pro local , ale vždy můžete jeden definovat ručně.
bash a zsh přidaly typeset s aliasem local v roce 1989 a 1991.
ksh88 přidal local jako nezdokumentovaný alias pro typeset cca 1990 a pdksh a jeho deriváty v roce 1994. posh (založeno na pdksh ) odstraněn typeset (pro přísné dodržování zásad Debianu, které vyžadují local , ale ne typeset ).
POSIX zpočátku protestoval proti specifikování typeset na základě toho, že byl dynamický rozsah. Takže ksh93 (přepis ksh v roce 1993 Davidem Kornem) přešel na statický místo toho. Také v ksh93, na rozdíl od ksh88, se místní rozsah provádí pouze pro funkce deklarované pomocí ksh syntaxe (function f {...} ), nikoli Bournovu syntaxi (f() {...} ) a local alias byl odstraněn.
Nicméně ksh93v-beta a finální verze od AT&T lze zkompilovat s experimentálním „bash“ režimem (ve skutečnosti povoleno ve výchozím nastavení), který provádí dynamické škálování (v obtěžujících formách funkcí, včetně local a typeset ), když ksh93 je vyvoláno jako bash . local se liší od typeset v takovém případě v tom, že jej lze vyvolat pouze z funkce. Ten bash režim bude ve výchozím nastavení v ksh2020 deaktivován pomocí local /declare aliasy na typeset budou zachovány, i když bash režim není zkompilován (ačkoli stále se statickým rozsahem).
yash (napsáno mnohem později), má typeset (à la ksh88), ale má pouze local jako alias od verze 2.48 (prosinec 2018).
@Schily spravuje potomka Bourne shellu, který byl nedávno vytvořen převážně v souladu s POSIX, nazvaný bosh která podporuje místní rozsah od verze 2016-07-06 (s local , podobně jako ash ).
Takže shelly podobné Bourneovi, které dnes mají nějakou formu lokálního rozsahu proměnných, jsou:
- ksh, všechny implementace a jejich deriváty (ksh88, ksh93, pdksh a deriváty jako posh, mksh, OpenBSD sh).
- ash a všechny jeho deriváty (NetBSD sh, FreeBSD sh, dash, busybox sh)
- bash
- zsh
- yash
- Bosh
Až k sh různých systémů, všimněte si, že existují systémy, kde je POSIX sh je v /bin (většina) a další, kde není (jako Solaris, kde je v /usr/xpg4/bin ). Pro sh implementace na různých systémech, které máme:
- ksh88:komerční Unices většinou odvozené od SysV (AIX, HP/UX, Solaris¹…)
- bash:většina systémů GNU/Linux, Cygwin, macOS
- ash:ve výchozím nastavení na Debianu a většině derivátů (včetně Ubuntu, Linuxu/Mintu), ačkoli může být administrátorem změněno na bash nebo mksh. NetBSD, FreeBSD a některé jejich deriváty (ne macOS).
- busybox sh:mnoho, ne-li většina vestavěných systémů Linux
- pdksh nebo odvozeniny:OpenBSD, MirOS
Nyní, kde se liší:
typeset(ksh, pdksh, bash, zsh, yash) vslocal(ksh88, pdksh, bash, zsh, ash, yash 2.48+).- statický (ksh93, v
function f {...}funkce), vs dynamický rozsah (všechny ostatní shelly). Například zdafunction f { typeset v=1; g; echo "$v"; }; function g { v=2; }; fvýstupy1nebo2. Podívejte se také naexportatribut ovlivňuje rozsah vksh93. - zda
local/typesetprostě udělá proměnnou místní (ash,bosh), nebo vytvoří novou instanci proměnné (jiné shelly). Například zdav=1; f() { local v; echo "${v:-empty}"; }; fvýstupy1neboempty(viz takélocalvar_inheritmožnost v bash 5.0 a vyšší). - u těch, které vytvářejí novou proměnnou, zda nová zdědí atributy (jako
export) a/nebo typ a které z proměnné v rodičovském oboru. Například, zdaexport V=1; f() { local V=2; printenv V; }; fvytiskne1,2nebo nic. - zda má tato nová proměnná počáteční hodnotu (prázdná, 0, prázdný seznam, v závislosti na typu,
zsh) nebo není původně nastaveno. - zda
unset Vna proměnné v lokálním rozsahu ponechá proměnnouunset, nebo jen loupe jedna úroveň rozsahu (mksh,yash,bashza určitých okolností). Například zdav=1; f() { local v=2; unset v; echo "$v"; }výstupy1nebo nic (viz takélocalvar_unsetmožnost v bash 5.0 a vyšší) - jako pro
export, zda se jedná o klíčové slovo, nebo pouze vestavěné nebo obojí a za jakých podmínek je považováno za klíčové slovo. - jako pro
export, zda jsou argumenty analyzovány jako normální argumenty příkazu nebo jako přiřazení (a za jakých podmínek). - zda můžete prohlásit místní proměnná, která byla v nadřazeném rozsahu pouze pro čtení.
- interakce s
v=value myfunctionkdemyfunctionsám deklarujevzda místní nebo ne.
To jsou ty, na které teď myslím. Podívejte se na chybu austin group výše pro více podrobností.
Pokud jde o místní rozsah možností shellu (na rozdíl od proměnných ), skořápky, které jej podporují, jsou:
ksh88(se syntaxí definice obou funkcí):provádí se ve výchozím nastavení, nevím o žádném způsobu, jak to zakázat.ash(od roku 1989):slocal -. To dělá$-parametr (který ukládá seznam možností) local.ksh93:nyní provedeno pouze profunction f {...}funkce.zsh(od roku 1995). Ssetopt localoptions. Také semulate -Laby byl režim emulace (a jeho sada možností) nastaven jako místní pro funkci.bash(od roku 2016) slocal -jako vash.
Související:Binární a textový režim příkazu Md5sum?