-a- 使 NAME 成為索引數組(如果支援)

-a- 使 NAME 成為索引數組(如果支援)

我的目標是了解「變數屬性」的一般概念希望它能幫助我理解Bash 中聲明了什麼

什麼是變數屬性?為什麼有人想要給變數屬性?為什麼在使用變數時僅僅創建變數並在執行中擴展它們還不夠“足夠”?

答案1

通常,變數是儲存值的地方。您為變數 ( ) 賦值var="some value",然後您可以透過變數擴充來呼叫該值(寫作"$var"相當於寫作"some value")。

當您為變數賦值時,或在 shell 存取變數的其他情況下,可以使變數執行一些特殊操作。變數的屬性是 shell 儲存在變數名稱和值旁邊的註釋,它告訴 shell 應用此特殊行為。

一個例子

declare -i x告訴 shellx必須只包含整數值。通常,當您為變數賦值時,shell 會取得等號右側展開後得到的字串,並將其儲存為變數的值。但是,如果變數具有整數屬性,則 shell 會將該字串解析為算術表達式,並儲存對該表達式求值的結果。例如:

$ 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 "+")

(第三行x=2+hello設定x為 2,因為hello它是一個未定義的變數名,未設定的變數預設被預設解釋為 0。)

更多範例

  • declare -l var聲明var必須僅包含小寫字母。當 shell 儲存變數的值時,它會將所有大寫字母轉換為小寫字母。
  • declare -u var進行另一個方向的轉換。
  • declare -r var設為var唯讀,這也是賦值的一種特殊行為:它會導致每個後續賦值var失敗。
  • declare -x var導致var被輸出到環境。對於此屬性,當 bash 執行外部命令時會發生特殊行為:外部命令看到的環境包含 shell 執行外部命令時 shell 正在匯出的變數。

答案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也可用於函數。

這些屬性中的每一個都有一種或多種用途:


-a- 使 NAME 成為索引數組(如果支援)

這並不是完全必要的,因為將參數設為數組會自動將其聲明為索引數組。使用它可以使您的程式碼更加明顯和可讀。


-A- 使名稱關聯數組(如果支援)

據我所知,這是完全必要的,因為嘗試設定關聯數組而不先聲明它會導致索引數組。

$ 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- 使名稱具有「整數」屬性

如果您想確保您的參數可以,則很有用僅有的保存整數。這也允許您對賦值執行算術擴充。

$ 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- 使名稱唯讀

這是一個很好的功能。它對於您想要設定一次並確保不更改的 shell/環境變數特別有用

$ 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- 匯出姓名

只是將變數導出到環境的另一種方法。


相關內容