`declare name`と`declare -g`は何をしますか?

`declare name`と`declare -g`は何をしますか?
  1. 何ですか

    declare name
    

    オプションが提供されない場合はどうなりますか?文字列変数の名前を宣言しますか?

  2. 何ですか

    declare -g
    

    変数名を指定しないとどうなりますか?グローバル属性を持つすべての変数の値を表示しますか?

declareBashのマニュアルの説明で答えが見つかりませんでした。

ありがとうございます。

ベストアンサー1

特に、シェルでの変数の処理と範囲の指定はbash非常にあいまいで直感的ではないかもしれません(時にはバグがあるかもしれません)。

ksh同様の機能がありますtypesetksh、、持っzshyashいますtypesetbashHasはtypeset別名として使用され、hasとdeclare互換性がありますksh。ほとんどのシェルにはこの機能があり、いくつかの機能を実装しています。zshdeclaretypesetbashexportreadonlylocaltypeset

bash作家が選んだdeclare理由の1つはtypesettypesetジャンルを設定するだけではありません。主張する変数:型、属性、および/または値とともに、指定された範囲に導入されます。

bash変数は次のとおりです。

  • 不明(例:設定または宣言されていない場合)
  • 文(以降declare
  • 設定します(値が与えられた場合は空になる可能性があります)。

タイプはさまざまです。

  • スカラー
  • 大量に
  • 連想配列

そして、次のようないくつかのプロパティがあります。

  • 整数
  • 出口
  • 読み取り専用
  • すべて小文字/すべて大文字
  • 命名参照

(タイプと属性の区別はかなりあいまいです)

型と属性のすべての組み合わせがサポートまたは有効なわけではありません。

現在declareの範囲で変数を宣言します。bash、動的範囲を実装しても、最も外側の範囲を特別に処理します。 ~と呼ばれるグローバル範囲。

declare呼び出されたときの動作は非常に異なります。グローバルスコープと関数にある場合(サブシェルによって導入された、または環境に関連する別のスコープについて話すものではありません)。

declare var関数内で操作を実行し、同じ変数が同じ範囲で宣言されていないと仮定すると、主張する新しい最初に設定されていない変数で、親var範囲(関数呼び出し元)に存在できる可能性のある変数を非表示にします。

これは、一種のスタックによって実装された動的スコープです。関数が終了すると、変数の状態、型、属性、および値は、関数が呼び出されたときの状態(スタックからポップ)に復元されます。

ただし、関数の外側(グローバルスコープ内)ではdeclare変数が実際に宣言されていますが、以前に設定されている場合は設定を解除するように初期化されません(declare同じ関数スコープ内で2番目に使用した場合と同じ)。型を指定すると、変数の値を変換できますが、すべての変換パスが許可されるわけではなく(スカラーから配列/ハッシュのみ)、属性を追加または削除できます。

bash関数は、最もdeclare -g外側(「グローバル」)の範囲のスタックの下部にある変数に対して機能します。

declare -gksh93からインスピレーションを受けるtypeset -g。ただし、ksh93グローバル範囲が異なり、各関数範囲とは別の静的範囲指定を実装しています。ダイナミックレンジで同じことを行うことはほとんど意味がありません。typeset -gmksh、、、zsh)を持つ他のすべてのyashシェルは、typeset -g新しいローカル変数をインスタンス化することなく、変数の一部のプロパティを変更するために使用されます。

では、bash人々は通常同じ目的で使用しますが、現在の変数ではなく最も外側の範囲変数に影響を与えるため、常に機能するわけではありません。

たとえば、

integer() { typeset -gi "$1"; }

変数を整数にするには//を使用できますmksh。まだ宣言されていない変数に対してのみ機能します。yashzshbash地元の発信者:

$ bash -c 'f() { declare a; integer a; a=1+1; echo "$a"; }; integer() { typeset -gi "$1"; }; f'
1+1
$ bash -c 'f() { integer a; a=1+1; echo "$a"; }; integer() { typeset -gi "$1"; }; f'
2

でも、でもありexport varませtypeset -x vartypeset -gx varexport変数がすでに存在する場合は、新しい変数を宣言せずに属性を追加します。readonlyvsもtypeset -r同じだ。

また、変数が現在のスコープで宣言されているunset場合にのみ設定を解除します(グローバルスコープは除外しますが、宣言は保持します。プロパティと値を削除し、変数は配列やハッシュではなくなります)bash。 )。それ以外の場合は、上記のスタックから変数レイヤーをポップします。bashバージョン5.0以降では、オプションlocalvar_unsetを設定して解決できます。

結論として:

 declare var

関数内で呼び出されたときにvar以前に同じ関数で宣言されていない場合は、型の変数を宣言します。スカラー属性がなく、初期設定されません。

関数の外部で呼び出されたvar場合、または同じ関数ですでに宣言されている場合は、新しい型や属性を指定しないため、何の効果もありません。

declare -g var

呼び出される場所ごとにvar最も外側(「グローバル」)範囲を宣言します。発表する,タイプスカラー、属性がなく、以前に範囲内で未知の場合は値がなく(すべての意図と目的に対して出力に表示されることを除いて、不明な変数と同じですtypeset -p)、その他は何もしません。

いずれの場合も、コマンドが実行されるコンテキストで変数にアクセスできない場合があります。

f() { local a; g; }; g() { typeset -g a=123; echo "$a"; }; f

何も出力されません。

おすすめ記事