
何ですか
declare name
オプションが提供されない場合はどうなりますか?文字列変数の名前を宣言しますか?
何ですか
declare -g
変数名を指定しないとどうなりますか?グローバル属性を持つすべての変数の値を表示しますか?
declare
Bashのマニュアルの説明で答えが見つかりませんでした。
ありがとうございます。
答え1
特に、シェルでの変数の処理と範囲の指定はbash
非常にあいまいで直感的ではないかもしれません(時にはバグがあるかもしれません)。
ksh
同様の機能がありますtypeset
。ksh
、、持っzsh
てyash
いますtypeset
。bash
Hasはtypeset
別名として使用され、hasとdeclare
互換性がありますksh
。ほとんどのシェルにはこの機能があり、いくつかの機能を実装しています。zsh
declare
typeset
bash
export
readonly
local
typeset
bash
作家が選んだdeclare
理由の1つはtypeset
、typeset
ジャンルを設定するだけではありません。主張する変数:型、属性、および/または値とともに、指定された範囲に導入されます。
のbash
変数は次のとおりです。
- 不明(例:設定または宣言されていない場合)
- 文(以降
declare
) - 設定します(値が与えられた場合は空になる可能性があります)。
タイプはさまざまです。
- スカラー
- 大量に
- 連想配列
そして、次のようないくつかのプロパティがあります。
- 整数
- 出口
- 読み取り専用
- すべて小文字/すべて大文字
- 命名参照
(タイプと属性の区別はかなりあいまいです)
型と属性のすべての組み合わせがサポートまたは有効なわけではありません。
現在declare
の範囲で変数を宣言します。bash
、動的範囲を実装しても、最も外側の範囲を特別に処理します。 ~と呼ばれるグローバル範囲。
declare
呼び出されたときの動作は非常に異なります。グローバルスコープと関数にある場合(サブシェルによって導入された、または環境に関連する別のスコープについて話すものではありません)。
declare var
関数内で操作を実行し、同じ変数が同じ範囲で宣言されていないと仮定すると、主張するㅏ新しい最初に設定されていない変数で、親var
範囲(関数呼び出し元)に存在できる可能性のある変数を非表示にします。
これは、一種のスタックによって実装された動的スコープです。関数が終了すると、変数の状態、型、属性、および値は、関数が呼び出されたときの状態(スタックからポップ)に復元されます。
ただし、関数の外側(グローバルスコープ内)ではdeclare
変数が実際に宣言されていますが、以前に設定されている場合は設定を解除するように初期化されません(declare
同じ関数スコープ内で2番目に使用した場合と同じ)。型を指定すると、変数の値を変換できますが、すべての変換パスが許可されるわけではなく(スカラーから配列/ハッシュのみ)、属性を追加または削除できます。
bash
関数は、最もdeclare -g
外側(「グローバル」)の範囲のスタックの下部にある変数に対して機能します。
declare -g
ksh93
からインスピレーションを受けるtypeset -g
。ただし、ksh93
グローバル範囲が異なり、各関数範囲とは別の静的範囲指定を実装しています。ダイナミックレンジで同じことを行うことはほとんど意味がありません。typeset -g
(mksh
、、、zsh
)を持つ他のすべてのyash
シェルは、typeset -g
新しいローカル変数をインスタンス化することなく、変数の一部のプロパティを変更するために使用されます。
では、bash
人々は通常同じ目的で使用しますが、現在の変数ではなく最も外側の範囲変数に影響を与えるため、常に機能するわけではありません。
たとえば、
integer() { typeset -gi "$1"; }
変数を整数にするには//を使用できますmksh
。まだ宣言されていない変数に対してのみ機能します。yash
zsh
bash
地元の発信者:
$ 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 var
んtypeset -gx var
。export
変数がすでに存在する場合は、新しい変数を宣言せずに属性を追加します。readonly
vsも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
何も出力されません。
答え2
declare name
name
属性なしで名前付き変数を宣言します。${name:not set}
たとえば、次を使用してその効果を確認できます。宣言された変数は配列ではなく、整数プロパティが設定されていないため、文字列変数として扱うことができますが、算術式ではゼロと評価されます。~からマンページ:
このオプションは、シェル関数内で実行されてい
-g
てもグローバルに変数を作成または変更することを可能にします。declare
他のすべての場合は無視されます。したがって、
declare -g
パラメータがない場合と同じですdeclare
。
答え3
declare name
からhttps://www.gnu.org/software/bash/manual/bashref.html#Bash-Builtins
変数を宣言し、属性を割り当てます。
オプションが指定されていないため、属性が割り当てられず、変数が作成されname
ました。値が指定されていないため、値は割り当てられませんでした。
declare -g
-g オプションは、ステートメントがシェル関数内で実行されていても、グローバルスコープで変数を強制的に生成または変更します。他のすべての場合は無視されます。
を提供しないため、name
変数が生成されないため無視されます。自分で見てください:
declare -g > foo
declare > bar
diff foo bar
唯一の違いは、Bash変数の値であり、$_
前のコマンドに基づいている可能性があり、PIPESTATUS
返された変数のリストに他の違いはありません。