web-dev-qa-db-ja.com

bashスクリプトで、宣言と通常の変数の違いは何ですか?

Bashスクリプトでは:

変数に名前を付けるだけで作成します。

abc=ok

または、declareを使用できます

declare abc=ok

違いは何ですか?

そしてなぜbashは変数を作成するために非常に多くの方法を作るのですか?

50
lovespring

help -m declareから:

[〜#〜]名前[〜#〜]

    declare-変数の値と属性を設定します。

[〜#〜] synopsis [〜#〜]

    declare [-aAfFgilnrtux] [-p] [name[=value] ...]

[〜#〜]説明[〜#〜]

    変数の値と属性を設定します。

    変数を宣言して属性を与えます。 NAMEが指定されていない場合は、すべての変数の属性と値を表示します。

    オプション:

      -f
        アクションまたは表示を関数名と定義に制限する
      -F
        表示を関数名のみに限定します(デバッグ時の行番号とソースファイルも含む)
      -g
        shell関数で使用する場合は、グローバル変数を作成します。それ以外の場合は無視されます
      -p
        各NAMEの属性と値を表示する

    属性を設定するオプション:

      -a
        nAMEインデックス付き配列を作成する(サポートされている場合)
      -A
        nAMEを連想配列にする(サポートされている場合)
      -i
        nAMEに「整数」属性を持たせる
      -l
        割り当て時にNAMEを小文字に変換する
      -n
        nAMEをその値で指定された変数への参照にします
      -r
        nAMEを読み取り専用にする
      -t
        nAMEに「trace」属性を持たせる
      -u
        割り当て時にNAMEを大文字に変換する
      -x
        nAMEをエクスポートするには

    +」の代わりに「-」を使用すると、指定された属性がオフになります。

    Integer属性を持つ変数は、変数に値が割り当てられたときに、算術評価(letコマンドを参照)が実行されます。

    関数で使用すると、declarelocalコマンドと同様にNAMEをローカルにします。 「-g」オプションは、この動作を抑制します。

    終了ステータス:
    無効なオプションが提供されるか、変数割り当てエラーが発生しない限り、成功を返します。

参照

    bash(1)

[〜#〜]実装[〜#〜]

    GNU bash、バージョン4.3.11(1)-release(i686-pc-linux-gnu)
    著作権(C)2013 Free Software Foundation、Inc.
    ライセンスGPLv3 +:GNU GPLバージョン3以降<http://gnu.org/licenses/gpl.html>

したがって、declareは変数値の設定に使用されますおよび属性.

2つの属性の使い方を非常に簡単な例で示します。

$ # First Example:
$ declare -r abc=ok
$ echo $abc
ok
$ abc=not-ok
bash: abc: readonly variable


$ # Second Example:
$ declare -i x=10
$ echo $x
10
$ x=ok
$ echo $x
0
$ x=15
$ echo $x
15
$ x=15+5
$ echo $x
20

上記の例から、通常の変数に対するdeclare変数の使用法を理解する必要があると思います。このタイプのdeclareationは、スクリプトでの関数やループで役立ちます。

タイピング変数:宣言またはタイプセット もご覧ください

39
Pandya

abc=okは、変数abcに値を割り当てます。 declare abcは、abcという変数を宣言します。 2つはdeclare abc=okとして組み合わせることができます。

Bashでは、他のシェルと同様に、文字列変数と配列変数を宣言する必要がないため、オプションを渡さない限り、declareは必要ありません。 declare -A abcabcを連想配列にするか、declare -rは変数を読み取り専用にします。ただし、関数内ではdeclareによって違いが生じます。これにより、変数が関数に対してローカルになり、関数外の変数の値(存在する場合)が保持されます。 (変数をローカルにしないdeclare -gを使用する場合を除きます。これは、他のオプションと組み合わせた場合に便利です。たとえば、declare -gAを使用して、関数にグローバル連想配列を作成します。)例:

f () {
  declare a
  a='a in f'
  b='b in f'
  echo "From f: a is $a"
  echo "From f: b is $b"
}
a='Initial a'
b='Initial b'
f
echo "After f: a is $a"
echo "After f: b is $b"

出力:

From f: a is a in f
From f: b is b in f
After f: a is Initial a
After f: b is b in f

declareビルトインでできるもう1つのことは、

declareビルトインはbashに固有です。それは強く刺激されており、kshのtypeset組み込みに非常に近く、bashは互換性のためにtypesetdeclareの同義語として提供します。 (bashが単にtypesetと呼ばなかった理由がわかりません)。 3番目の同義語、localがあります。互換性のためにexportもあり、これはdeclare -xと同じです(すべてのBourneスタイルのシェルと)。