Bash

能否解釋一下;使用 array= 之間的數組行為差異(com和d__)和d_一個ray_=((C這米米一種nd)一種nd一種rr一種是=(( command ) and array=(( 命令 ) )?

  • June 17, 2017

我理解命令替換。我了解子殼。我不明白為什麼使用子外殼會改變數組的結構。

鑑於此命令輸出:(使用 openstack 命令不相關)

bash$ floating ip list -c 'Floating IP Address' -f value
172.25.250.106
172.25.250.107
172.25.250.101

嘗試在數組中擷取,但所有地址都以元素 0 結尾:

bash$ float=$( openstack floating ip list -c 'Floating IP Address' -f value )
bash$ echo ${float[@]}
172.25.250.106 172.25.250.107 172.25.250.101
bash$ echo ${#float[@]}
1
bash$ echo ${float[0]}
172.25.250.106 172.25.250.107 172.25.250.101
bash$ echo ${#float[0]}
44

整個輸出被擷取為一個字元串,而不是解析為元素。我期待每個單詞都成為一個元素。當我重複此操作以確保引用每個 IP 地址時(使用 -f csv 而不是 -f 值),結果是相同的。

接下來,我將命令替換放在子 shell 中:

bash$ unset float
bash$ float=( $( openstack floating ip list -c 'Floating IP Address' -f value ) )
bash$ echo ${float[@]}
172.25.250.106 172.25.250.107 172.25.250.101
bash$ echo ${#float[@]}
3
echo ${float[0]}
172.25.250.106
echo ${#float[0]}
14

這是我最初預期的行為。我還注意到使用 read 語句建構數組按預期工作:

bash$ unset float
bash$ read -a float <<< $( openstack floating ip list -c 'Floating IP Address' -f value )
bash$ echo ${float[@]}
172.25.250.106 172.25.250.107 172.25.250.101
bash$ echo ${#float[@]}
3
echo ${float[0]}
172.25.250.106
echo ${#float[0]}
14

我想看看原來的命令替換工作。想知道我是否應該先設置一個欄位分隔符或者我還缺少什麼。我試圖了解導致行為差異的原因。

float=$( openstack floating ip list -c 'Floating IP Address' -f value )

這將創建一個字元串變數,而不是數組變數。該字元串是命令的輸出,減去任何尾隨換行符。

如果您嘗試將字元串變數用作數組,則會將其視為單元素數組,其中字元串值位於位置 0。

float=( $( openstack floating ip list -c 'Floating IP Address' -f value ) )

這不會“將命令替換放在子 shell 中”。命令替換本身$(…)會創建一個子shell。它周圍的括號不會創建另一個子shell:它們創建一個數組。該數組包含從獲取命令輸出、刪除尾隨換行符、拆分為空格分隔的單詞列表以及替換該列表中包含與一個或多個文件匹配的萬用字元的任何元素所產生的單詞列表匹配文件名的列表。

當括號位於預期命令的位置時,括號會創建一個子shell。在var=(…)中,等號之後的預期不是命令,而是賦值。在這種情況下,括號表示該值是一個數組。

引用自:https://unix.stackexchange.com/questions/371723