2013-08-01 75 views
2

這是一個很難解釋。考慮變量allfirstlast,並some如何將用戶輸入解釋爲變量名稱?

a="apple mcintosh" 
b="banana plantain" 
c="coconut cashew" 
all="$a $b $c" 
first="$a" 
last=$c" 
some="$a $c" 

以下是我有:

echo "What do you want to install?" 
echo "all, first, last, or some?" 
read userinput 

假設用戶類型all,他的投入,應作爲一個變量的名稱進行處理:我想要下一個命令是pacman -S $all(相當於pacman -S apple mcintosh banana plantain coconut cashew)。同樣,如果用戶鍵入firstlast,則下一個命令必須是pacman -S $first $last(實際上它應該執行pacman -S apple mcintosh coconut cashew)。

我使用case/esacuserinput轉換爲變量,但我正在尋找更靈活和優雅的解決方案,因爲此方法不允許多個輸入。

case $userinput in            
    all) result="$all";; 
    first) result="$first";; 
    *)  exit;; 
esac 

pacman -S $result 

回答

4

什麼你以後是indirect variable reference,它的形式${!var}

3.5.3殼牌參數擴展

[...]如果第一字符參數是一個感嘆號(!),引入了一個變量間接的級別。 Bash使用由參數的其餘部分形成的變量的值作爲變量的名稱;這個變量然後被擴展,並且該值被用於替換的其餘部分,而不是參數本身的值。這被稱爲間接擴展。

例如:

$ a="apple mcintosh" 
$ b="banana plantain" 
$ c="coconut cashew" 
$ all="$a $b $c" 
$ first="$a" 
$ last="$c" 
$ some="$a $c" 
$ read userinput 
all 
$ result=${!userinput} 
$ echo $result 
apple mcintosh banana plantain coconut cashew 

要展開的多個項目,用read -a讀字到一個數組:

$ read -a userinput 
first last 
$ result=$(for x in ${userinput[@]}; do echo ${!x}; done) 
$ echo $result 
apple mcintosh coconut cashew 
+1

好的答案!我只寫了一個使用'eval'的函數,但是你的方法更加優雅,所以我放棄了我的答案。 – user1146332

+0

它確實很優雅,但它仍然無法處理多個輸入。不過,很高興終於知道它是如何被調用的。 – octosquidopus

+0

@octosquidopus已更新爲使用多字輸入:-) –

1

對於從選擇列表中讀取用戶輸入,bash的select是你需要什麼。此外,當你開始問「我怎麼動態地構建一個變量名」,認爲關聯數組來代替:

a="apple mcintosh" 
b="banana plantain" 
c="coconut cashew" 

declare -A choices 
choices[all]="$a $b $c" 
choices[first]="$a" 
choices[last]="$c" 
choices[some]="$a $c" 

PS3="What do you want to install? " 

select choice in "${!choices[@]}"; do 
    if [[ -n $choice ]]; then 
     break 
    fi 
done 

echo "you chose: ${choices[$choice]}" 

以上不處理多個選擇。在這種情況下,則(仍使用「選擇」陣列從上面):

options=$(IFS=,; echo "${!choices[*]}") 
read -rp "What do you want to install ($options)? " -a response 
values="" 
for word in "${response[@]}"; do 
    if [[ -n ${choices[$word]} ]]; then 
     values+="${choices[$word]} " 
    fi 
done 
echo "you chose: $values" 

這使用read-a選項來讀取響應到一個數組。它看起來像:

$ bash select.sh 
What do you want to install (some,last,first,all)? first middle last 
you chose: apple mcintosh coconut cashew 
相關問題