2017-03-03 94 views
0

比方說,我有一堆年初設定的常量,我按字母順序排列爲更好地瞭解一個腳本:bash的變量向前聲明

declare -r home_folder=/home/ 
declare -r user_folder=$home_folder$user_name/ 
declare -r user_name=$USER 

顯然,第二行的評價不會給因爲bash只進行一次評估,因此稍後調用$user_folder仍然會給出/home/。有什麼辦法可以解決這個問題嗎?

編輯:首選的解決方案看起來像

declare -r home_folder=/home/ 
declare -r user_folder=$home_folder$pointer-to-user_name/ 
declare -r user_name=$USER 

與時user_folder評估被評估的指針,但我不知道是否有可能這在bash。

+0

ALPHABETICALLY ????如何在語義上對它們進行排序,那麼可能你的問題本身就會消失。 (按字母順序... *不相信的搖頭*)請不要感到難過。我的建議:嘗試按照它們「出現」的順序排列,然後這個問題就消失了。按字母順序排列沒有足夠的優勢(如果你問我)沒有足夠的優勢來證明這一點。 – Alfe

+1

Shell腳本是表達行爲的迭代方式,執行順序不是基於依賴關係的。你想要達到的目標要麼是讀完所有可能的任務,要麼只執行滿足依賴關係的任務,直到完成所有任務或剩下的所有任務都有未滿足的依賴關係,或者構建某種依賴關係樹並遵循它。你可以構建它,或者更可能的是,根據它們的語義來決定順序賦值是否合理,並有助於避免循環依賴,尤其是使用'set -u'時。 – Fred

+0

除了命令的名稱之外,shell中沒有實際的變量聲明。 'declare -r user_name'只設置*名稱*上的一個屬性;除非實際爲其分配值,否則'user_name'仍未定義。 (OK,'-r'就是一個不好的例子,因爲未能分配給一個你認爲只讀的名字會有效地阻止你通過這個名字定義一個變量。) – chepner

回答

0

bash腳本是從上到下逐行執行的,因爲它只是邏輯的。與大量其他編程語言一樣。變量總是包含您之前分配給它的值。

也許我不明白你的意思是「前向聲明」。或者你將「賦值」與「聲明」混合在一起?

+0

不知道我是不是混在一起......我想要做的事情就像是'a = pointer_to_b'和'b = foo',所以如果我寫'$ a',我會得到'foo'。 – Wanderer

+0

bash afaik中沒有指針。可能有其他方法來完成你正在嘗試做的事情。你可以嘗試eval:a ='$ b'; B = FOO; eval echo $ a; c ='eval echo $ a'; $ c – khaoz

+0

或a ='eval $ b'; B =回聲; $ a - 但你不能像真正的指針那樣使用它 – khaoz

0

您可以通過shell函數替換所有的變量:

home_folder() { echo "/home/"; } 
user_folder() { echo "$(home_folder)$(user_name)/"; } 
user_name() { echo "$USER"; } 

然後在你使用的代碼,你可以隨時記$(xxx)訪問的xxx內容(而不是通常的$xxx${xxx})。

但是這會減慢一切,因爲每個值在使用時都會重新創建。也許你可以忍受這一點。

+0

可能是目前最好的賭注,但我不確定我想寫這樣的代碼...有沒有辦法像'a = pointer_to_b'和'b = foo',所以如果我寫'$ a'我得到'foo'? – Wanderer

+1

那麼,你所尋找的是非腳本語言的一個特性,它在執行之前得到編譯。在這些範圍內,每個常量的典型值都是正好一個值。然後,編譯器發現並拒絕相反的任務。在腳本上下文中,這是處理不同的。您可以隨時隨地覆蓋價值持有者。只考慮當前值。因此,引用一個尚未設置的值不會導致任何查找,但會導致運行時錯誤或(像在bash中)默認值(如空字符串)。 – Alfe

+0

好的,謝謝你指出這個區別。我沒有想到這樣的構造在一般情況下會成爲bash/shell中的一大問題。 – Wanderer