私は「可変属性」の一般的な概念を理解することを目指しています。Bashで宣言するもの。
変数属性とは何ですか? 変数に属性を与えたいのはなぜでしょうか? 変数を操作するときに、変数を作成して実行時に展開するだけではなぜ「十分」ではないのでしょうか?
答え1
通常、変数は値を格納する場所です。変数 ( var="some value"
) に値を代入し、その後は変数展開 ( と書くこと"$var"
は と書くことと同等"some value"
) で値を呼び出すことができます。
変数に値を割り当てたとき、またはシェルが変数にアクセスするその他の状況で、特別な動作を行う変数を作成することができます。変数の属性は、シェルが変数の名前と値の横に保存する注釈であり、シェルにこの特別な動作を適用するように指示します。
一例
declare -i x
シェルx
に、変数には整数値のみを含める必要があることを伝えます。通常、変数に値を割り当てると、シェルは等号の右側を展開した結果の文字列を取得し、それを変数の値として保存します。ただし、変数に整数属性がある場合、シェルはその文字列を算術式として解析し、その式を評価した結果を保存します。例:
$ x=2+2; echo $x
2+2
$ declare -i x; x=2+2; echo $x
4
$ declare -i x; x=2+hello; echo $x
2
$ declare -i x; x=2+
bash: 2+: syntax error: operand expected (error token is "+")
(3 行目の は定義されていない変数名であるため 2 にx=2+hello
設定され、設定されていない変数はデフォルトで 0 として暗黙的に解釈されます。)x
hello
その他の例
declare -l var
小文字のみを含む必要があることを宣言しますvar
。シェルが変数の値を保存するときに、大文字を小文字に変換します。declare -u var
逆方向の変換を行います。declare -r var
読み取り専用になりますvar
が、これは割り当ての特殊な動作でもあります。これにより、後続のすべての割り当てがvar
失敗します。declare -x var
環境にエクスポートされますvar
。この属性の場合、bash が外部コマンドを実行するときに特別な動作が発生します。外部コマンドは、シェルが外部コマンドを実行するときにシェルがエクスポートしている変数を含む環境を参照します。
答え2
からhelp declare
:
Options which set attributes:
-a to make NAMEs indexed arrays (if supported)
-A to make NAMEs associative arrays (if supported)
-i to make NAMEs have the `integer' attribute
-l to convert the value of each NAME to lower case on assignment
-n make NAME a reference to the variable named by its value
-r to make NAMEs readonly
-t to make NAMEs have the `trace' attribute
-u to convert the value of each NAME to upper case on assignment
-x to make NAMEs export
注:declare
関数にも使用できます。
これらの属性にはそれぞれ 1 つまたは複数の用途があります。
-a
- NAME をインデックス配列にする(サポートされている場合)
パラメータを配列として設定すると、自動的にインデックス付き配列として宣言されるため、これは必ずしも必要ではありません。これを使用すると、コードがより明確で読みやすくなります。
-A
- NAMEを連想配列にする(サポートされている場合)
私の知る限り、最初に連想配列として宣言せずに連想配列を設定しようとすると、インデックス付き配列が生成されるため、これは完全に必要です。
$ assoc=([foo]=bar)
$ declare -p assoc
declare -a assoc=([0]="bar")
$ unset assoc
$ declare -A assoc
$ assoc=([foo]=bar)
$ declare -p assoc
declare -A assoc=([foo]="bar" )
-i
- NAMEに「integer」属性を持たせる
パラメータがのみ整数を保持します。これにより、代入時に算術展開を実行することもできます。
$ declare -i a
$ a=foo
$ echo $a
0
$ a=1+1
$ echo $a
2
-l
- 代入時に各NAMEの値を小文字に変換する
パラメータの値が常にすべて小文字になることを保証します。これは私が知らなかった非常に優れた機能で、将来的には使用することになるでしょう。これにより、複雑なパラメータ展開や次のような別のユーティリティを使用する必要がなくなります。tr
$ declare -l foo=Bar
$ echo $foo
bar
-n
- NAMEをその値で名付けられた変数への参照にする
eval
間接参照のようなものです。これにより、多くのスクリプトでの使用が不要になります。
$ a=foo
$ declare -n b=a
$ echo $b
foo
-r
- NAMEを読み取り専用にする
これは良い機能です。一度設定して変更されないようにしたいシェル/環境変数に特に便利です。
$ declare -r foo=bar
$ echo $foo
bar
$ foo=baz
-bash: foo: readonly variable
-t
- NAMEに「trace」属性を持たせる
これについてはよく分かりません。関数にのみ適用されるのではないかと思います。
-u
- 代入時に各NAMEの値を大文字に変換する
似ている-l
が反対
$ declare -u foo=bAr
$ echo $foo
BAR
-x
- NAMEをエクスポートする
変数を環境にエクスポートする別の方法です。