2016-02-14 50 views
2

bash我可以這樣做:使用「改爲」從CLI設置變量

$ ERR_TYPE=$"OVERLOAD" 
$ echo $ERR_TYPE 
OVERLOAD 
$ read ${ERR_TYPE}_ERROR 
1234 
$ echo $OVERLOAD_ERROR 
1234 

這個偉大的工程,以動態地設置我的變量名;在腳本中它不起作用。我試過了:

#!/bin/env bash 

ERR_TYPE=("${ERR_TYPE[@]}" "OVERLOAD" "PANIC" "FATAL") 

for i in "${ERR_TYPE[@]}" 
do 
    sh -c $(echo ${i}_ERROR=$"1234") 
done 
echo $OVERLOAD_ERROR # output is blank 

    # I also tried these: 
    # ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # command not found 
    # read ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # it never terminates 

如何設置一個變量,就像我從CLI執行的操作一樣,但是在腳本中?謝謝

回答

2

當您使用動態變量名稱,而不是關聯數組,你真的需要質疑自己的做法。

err_type=("OVERLOAD" "PANIC" "FATAL") 
declare -A error 
for type in "${err_type[@]}"; do 
    error[$type]=1234 
done 

然而,在bash你會使用declare

declare "${i}_error=1234" 

你的方法失敗,因爲你生成一個新的外殼,將命令傳遞OVERLOAD_ERROR=1234,然後在shell退出。您當前的shell完全不受影響。

擺脫使用ALLCAPSVARNAMES的習慣。有一天,你會寫PATH=...,然後想知道你的劇本爲什麼壞了。

+0

關於'declare'函數vs'eval',後者是不是真的甚至打算用它來設置變量? S. Klumpers方法可行,但我還沒有接受答案,因爲我想確保。謝謝!哎呀,我的意思是謝謝! (ALLCAPS = not good practice noted)... –

+0

'eval'旨在將字符串評估爲shell代碼,而不是專門針對變量。 'declare'旨在創建變量,可能具有某個特定屬性(如關聯/索引數組,整數,小寫等) –

1

我會用eval。 我認爲這將被認爲是不好的做法,雖然(它有一些事情與事實eval是「邪惡的」,因爲它可以讓壞的輸入或東西):

eval "${i}_ERROR=1234" 
+0

我修正了它,當有疑問時只是添加更多的evals。 –

+0

嘿,看看你!你將永遠被稱爲「伊娃博士!」! :D ...是的,這是有效的...但像你說的那樣是正確的方式?即使它正在工作,我甚至有點緊張,甚至不知道它是如何工作的,爲什麼。如果可以在while循環中使用「read」,我也不會介意......這只是因爲我對while循環不夠熟悉,並且讀到無論什麼原因我都可以終止它。如果它不能完成,這是唯一的方法,我會很樂意接受你的答案......再次感謝 –

+0

eval命令通過評估所有表達式並返回結果,echo打印它,因爲它在一個子shell中將成爲下一個評估的參數。 –

1

如果這個變量將舉行一個數字,你可以使用let

#!/bin/bash 

ERR_TYPE=("OVERLOAD" "PANIC" "FATAL") 

j=0 
for i in "${ERR_TYPE[@]}" 
do 
    let ${i}_ERROR=1000+j++ 
done 
echo $OVERLOAD_ERROR 
echo $PANIC_ERROR 
echo $FATAL_ERROR 

此輸出:

1000 
1001 
1002 
+0

我追加的部分可以是數字或字符串。不過謝謝你的回答,我以前不知道'let' - 而且很高興知道它是用於數字的。 –