BashとZshがlocal
をサポートしていることを知っています 変数ですが、POSIX互換のシェルしかないシステムもあります。そしてlocal
POSIXシェルでは未定義です。
そこで、どのシェルがlocal
をサポートしているかを尋ねたいと思います。 ローカル変数を定義するためのキーワード?
<ストライク>編集 :シェルについて私はデフォルトの/bin/sh
を意味します シェル。
承認された回答:
local
をサポートするほど簡単ではありません か否か。構文にはさまざまなバリエーションがあり、ローカルスコープのいずれかの形式を持つシェル間でどのように実行されるかが異なります。
そのため、すべてに同意する基準を考案することは非常に困難です。その面でのPOSIXの取り組みについては、http://austingroupbugs.net/bug_view_page.php?bug_id=767を参照してください。
ローカルスコープは、80年代初頭にkshで最初に追加されました。
関数でローカル変数を宣言する構文は、typeset
を使用していました。 :
function f {
typeset var=value
set -o noglob # also local to the function
...
}
(関数のサポートは後でBourneシェルに追加されましたが、構文が異なります(f() command
)およびksh
後でそのサポートも追加しました。 Bourneシェルにはローカルスコープがありませんでした(もちろんサブシェル経由を除く))
local
組み込みのAFAIKは、1989年にAlmquistシェル(BSD、dash、busybox shで使用)に最初に追加されましたが、ksh
とは大幅に異なる動作をします。 のtypeset
。 ash
派生物はtypeset
をサポートしていません local
のエイリアスとして 、ただし、いつでも手動で定義できます。
bashとzshがtypeset
を追加しました local
のエイリアス それぞれ1989年と1991年に。
ksh88がlocal
を追加しました typeset
の文書化されていないエイリアスとして 1990年頃、1994年のpdkshとその派生物。posh
(pdksh
に基づく )typeset
を削除しました (local
を必要とするDebianポリシーに厳密に準拠するため 、ただしtypeset
ではありません 。
POSIXは当初、typeset
の指定に反対しました 動的であるという理由で スコーピング。そのため、ksh93(1993年にDavid Kornがkshを書き直したもの)を staticに切り替えました。 代わりにスコーピング。また、ksh88とは対照的に、ksh93では、ローカルスコープはksh
で宣言された関数に対してのみ実行されます。 構文(function f {...}
)、ボーン構文ではありません(f() {...}
)およびlocal
エイリアスが削除されました。
ただし、AT&Tのksh93v-ベータ版と最終バージョンは、動的スコーピング(local
を含む面倒な形式の関数)を実行する実験的な「bash」モード(実際にはデフォルトで有効)でコンパイルできます。 およびtypeset
)ksh93
の場合 bash
として呼び出されます 。 local
typeset
とは異なります その場合、関数内からのみ呼び出すことができます。そのbash
local
を使用すると、ksh2020ではデフォルトでモードが無効になります。 /declare
typeset
のエイリアス bashモードがコンパイルされていない場合でも保持されます(ただし、静的スコープは使用されます)。
yash
(ずっと後で書かれています)、typeset
があります (àlaksh88)が、local
しかありませんでした バージョン2.48(2018年12月)以降のエイリアスとして。
@Schilyは、最近ほとんどPOSIXに準拠するようになった、bosh
と呼ばれるBourneシェルの子孫を維持しています。 バージョン2016-07-06以降のローカルスコープをサポートします(local
を使用) 、ash
に似ています 。
したがって、今日の変数のローカルスコープの形式を持つボーンのようなシェルは次のとおりです。
- ksh、すべての実装とその派生物(ksh88、ksh93、pdksh、およびposh、mksh、OpenBSD shなどの派生物)。
- ashとそのすべての派生物(NetBSD sh、FreeBSD sh、dash、busybox sh)
- バッシュ
- zsh
- ヤシュ
- bosh
sh
まで さまざまなシステムがありますが、POSIX sh
が存在するシステムがあることに注意してください。 /bin
にあります (ほとんど)、およびそうでないその他の場所(/usr/xpg4/bin
にあるSolarisなど) )。 sh
の場合 さまざまなシステムでの実装:
- ksh88:ほとんどのSysV派生の商用Unices(AIX、HP / UX、Solaris¹…)
- bash:ほとんどのGNU / Linuxシステム、Cygwin、macOS
- ash:デフォルトではDebianおよびほとんどの派生物(Ubuntu、Linux / Mintを含む)ですが、管理者はbashまたはmkshに変更できます。 NetBSD、FreeBSDおよびそれらの派生物のいくつか(macOSではない)。
- busybox sh:ほとんどではないにしても多くの組み込みLinuxシステム
- pdkshまたは派生物:OpenBSD、MirOS
さて、それらが異なるところ:
typeset
(ksh、pdksh、bash、zsh、yash)とlocal
(ksh88、pdksh、bash、zsh、ash、yash 2.48+)。- static(ksh93、in
function f {...}
関数)、vs動的スコーピング(他のすべてのシェル)。たとえば、function f { typeset v=1; g; echo "$v"; }; function g { v=2; }; f
1
を出力します または2
。export
の方法もご覧ください 属性はksh93
のスコープに影響します 。 local
かどうか /typeset
変数をローカルにするだけです (ash
、bosh
)、または変数(他のシェル)の新しいインスタンスを作成します。たとえば、v=1; f() { local v; echo "${v:-empty}"; }; f
1
を出力します またはempty
(localvar_inherit
も参照してください。 bash 5.0以降のオプション)。- 新しい変数を作成する変数を使用して、新しい変数が属性を継承するかどうか (
export
のように )および/またはタイプ、および親スコープの変数からのタイプ。たとえば、export V=1; f() { local V=2; printenv V; }; f
1
を出力します 、2
または何も。 - その新しい変数に初期値があるかどうか(空、0、空のリスト、タイプに応じて、
zsh
)または最初は設定されていません。 -
unset V
かどうか ローカルスコープ内の変数で、変数をunset
のままにします 、または単にはがす 1レベルのスコーピング(mksh
、yash
、bash
状況によっては)。たとえば、v=1; f() { local v=2; unset v; echo "$v"; }
1
を出力します または何もありません(localvar_unset
も参照してください bash 5.0以降のオプション) -
export
のように 、それがキーワードであるか、単なる組み込みであるか、またはその両方であるか、どのような条件下でキーワードと見なされるか。 -
export
のように 、引数が通常のコマンド引数として解析されるか、割り当てとして解析されるか(およびどのような条件下で)。 - ローカルを宣言できるかどうか 親スコープで読み取り専用だった変数。
-
v=value myfunction
との相互作用 ここで、myfunction
それ自体がv
を宣言します ローカルかどうか。
それが私が今考えているものです。詳細については、上記のオースティングループのバグを確認してください。
シェルのローカルスコープに関する限りオプション (変数とは対照的に )、それをサポートするシェルは次のとおりです:
-
ksh88
(両方の関数定義構文を使用):デフォルトで実行されますが、無効にする方法はわかりません。 -
ash
(1989年以降):local -
。$-
になります パラメータ(オプションのリストを格納する)ローカル。 -
ksh93
:function f {...}
に対してのみ実行されるようになりました 機能。 -
zsh
(1995年以降)。setopt localoptions
を使用 。emulate -L
も使用します エミュレーションモード(およびそのオプションのセット)を関数に対してローカルにするため。 -
bash
(2016年以降)local -
ash
のように 。
関連:Md5sumコマンドのバイナリおよびテキストモード?