GNU/Linux >> Linux の 問題 >  >> Linux

ローカル変数を定義するための`local`キーワードをサポートするシェルのリスト?

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とは大幅に異なる動作をします。 のtypesetash 派生物はtypesetをサポートしていません localのエイリアスとして 、ただし、いつでも手動で定義できます。

bashとzshがtypesetを追加しました localのエイリアス それぞれ1989年と1991年に。

ksh88がlocalを追加しました typesetの文書化されていないエイリアスとして 1990年頃、1994年のpdkshとその派生物。poshpdkshに基づく )typesetを削除しました (localを必要とするDebianポリシーに厳密に準拠するため 、ただしtypesetではありません 。

POSIXは当初、typesetの指定に反対しました 動的であるという理由で スコーピング。そのため、ksh93(1993年にDavid Kornがkshを書き直したもの)を staticに切り替えました。 代わりにスコーピング。また、ksh88とは対照的に、ksh93では、ローカルスコープはkshで宣言された関数に対してのみ実行されます。 構文(function f {...} )、ボーン構文ではありません(f() {...} )およびlocal エイリアスが削除されました。

ただし、AT&Tのksh93v-ベータ版と最終バージョンは、動的スコーピング(localを含む面倒な形式の関数)を実行する実験的な「bash」モード(実際にはデフォルトで有効)でコンパイルできます。 およびtypesetksh93の場合 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
関連:異なるファイルの2つの列を比較し、一致する場合は印刷しますか?

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を出力します または2exportの方法もご覧ください 属性はksh93のスコープに影響します 。
  • localかどうか /typeset 変数をローカルにするだけです (ashbosh )、または変数(他のシェル)の新しいインスタンスを作成します。たとえば、v=1; f() { local v; echo "${v:-empty}"; }; f 1を出力します またはemptylocalvar_inheritも参照してください。 bash 5.0以降のオプション)。
  • 新しい変数を作成する変数を使用して、新しい変数が属性を継承するかどうか (exportのように )および/またはタイプ、および親スコープの変数からのタイプ。たとえば、export V=1; f() { local V=2; printenv V; }; f 1を出力します 、2 または何も。
  • その新しい変数に初期値があるかどうか(空、0、空のリスト、タイプに応じて、zsh )または最初は設定されていません。
  • unset Vかどうか ローカルスコープ内の変数で、変数をunsetのままにします 、または単にはがす 1レベルのスコーピング(mkshyashbash 状況によっては)。たとえば、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 -$-になります パラメータ(オプションのリストを格納する)ローカル。
  • ksh93function f {...}に対してのみ実行されるようになりました 機能。
  • zsh (1995年以降)。 setopt localoptionsを使用 。 emulate -Lも使用します エミュレーションモード(およびそのオプションのセット)を関数に対してローカルにするため。
  • bash (2016年以降)local - ashのように 。

関連:Md5sumコマンドのバイナリおよびテキストモード?
Linux
  1. シェルが知っているすべてのコマンドを一覧表示しますか?

  2. Go For It –タイマー付きの最新のToDoリスト

  3. Bash for ループの例

  1. RedHatとSUSEがOpenLDAPのサポートを撤回すると発表

  2. SysAdmins用の80のLinux監視ツール

  3. filename に続く tail -f の代替

  1. ネストされた仮想化サポート用にvirt-managerを設定する方法は?

  2. Bashスクリプトの変数用のスペース?

  3. Linux – Ipv6対応の一般的なLinuxサポート?