我的問題是,當我開始編寫腳本時,我遇到了幾個變數範圍問題,這導致了導出幾乎所有變數的壞習慣。
現在我的程式碼已經變得相當大,我正在考慮清理它,其中一部分是刪除一堆無用的導出。不幸的是,我不確定我對變數作用域的了解是否完整。即使在閱讀了有關該主題的幾頁之後。
我所知道的(希望是對的):
1-導出變數使其內容可供子 shell 進程使用:
export myvar="content"
2-像這樣在括號中完成的內容將受到刪除導出的影響(據我所知,這是聲明/使用子shell的唯一方法):
$(grep "content" <<< $myvar)
3-未設定其範圍而宣告的變數是全域的:
myvar="content"
4-由於我沒有聲明任何局部變量,所以我不必擔心在我的函數中引起問題:
local myvar="i don't use this"
問題:
1-除了我的程式碼沒有散發出明顯的新手氣息之外,繼續刪除無用的匯出還有什麼意義嗎?
2-如果我繼續這樣做,還有什麼我應該注意的可能會受到影響並破壞我的程式碼的事情嗎?或者我的知識有錯誤/不完整嗎?
3-如果您知道寫得好的(且完整的)變數範圍參考,請分享連結。
答案1
只要您不使用export
兩次評估,您就可以刪除所有匯出,而不會對導出的變數產生任何影響。兩次評估我的意思是:
var1=var2
export "${var1}=var3"
echo "$var2"
var3
相反,只需使用:
set -a
....在腳本的頂部。此後定義的所有變數都將自動exported
- 其中包括您以前可能沒有export
編輯過的變數。或者,您可以只set -a
使用腳本的一部分,然後set +a
取消設定它 - 它也可以作為函數使用。
但子 shell 無論如何都會自動繼承變數值,所以:
var1=value
( echo "$(echo "$var1")" )
value
export
在這種情況下沒有什麼區別。
但是,如果您的腳本呼叫另一個腳本或解釋您編輯的值的任何其他可執行文件,export
並且您停止使用export
它們,那麼這些值將不再在其環境中可用。在下面的範例中,我使用 shell 變數$PS1
(定義互動式 shell 提示的內容)來示範export
ed 變數的變更如何影響子進程。
export PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i
###OUTPUT###
this is another executable
> exit
exit
但 ...
PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i
###OUTPUT###
sh-4.3$ exit
exit
但話又說回來,如果您在呼叫進程時明確聲明環境變數......
PS1="$(printf "this is another executable\n > ")"
{
echo exit | PS1=$PS1 sh -i
echo exit | sh -i
}
###OUTPUT###
this is another executable
> exit
exit
sh-4.3$ exit
exit