在 shell 中建立的變數可分為 shell 變數和環境變數, 兩者最簡單的區分就是:
- shell 變數:只在當前 shell 下有效, 即使啟動子 shell, 這些變數也不會繼承到子 shell 中。
- 環境 (environment )變數:會在當前 shell 以及子 shell 中生效。
以下我們個別說明。
shell 變數
首先來看 shell 變數:
$ SHELL_X=20
$ set | grep SHELL_X
SHELL_X=20
$ env | grep SHELL_X
$ bash
> set | grep SHELL_X
> env | grep SHELL_X
>
建立變數的方式非常簡單, 就是:
變數名稱=變數內容
要記得等號兩邊不要有空白, 變數內容如果有空白, 就要用雙引號括起來。這樣建立起來的變數是 shell 變數, 所以使用 set
列出所有變數時, 會看到 SHELL_X
出現在清單中, 但是用 env
列出環境變數時, 就不會出現了。
環境變數
建立環境變數的方式是使用 export
指令:
$ ENV_X=20
$ set | grep ENV_X
ENV_X=20
$ env | grep ENV_X
$ export ENV_X
$ env | grep ENV_X
ENV_X=20
$ bash
> set ENV_X
> set | grep ENV_X
ENV_X=20
_=ENV_X
> env | grep ENV_X
ENV_X=20
>
你可以看到使用 export
將 ENV_X
變成環境變數後, 不會是使用 set
還是 env
列出變數, 都會看到 ENV_X
, 而且在啟動的子 shell 中, 仍然可以看到 ENV_X
。
利用設定檔設定環境變數
剛剛設定的環境變數在 shell 結束後就會消失, 如果想要讓 shell 執行起來後就會自動設定特定的環境變數, 在實際解說各種 shell 的設定檔前, 先來說明 shell 的模式:
- login shell:如果需要輸入帳密認證才能啟動的 sehll 就是 login shell, 否則就不是 login shell。例如在當前 shell 下執行
zsh
或是bash
, 並不需要輸入帳密, 就不是 login shell。 - interactive shell:有配置新的終端機的 shell 稱為 interactive shell, 例如以 shell 直接執行腳本時並不會配置新的終端機, 所以並不是 interactive shell。
是否為 login shell 或 interactive shell 會決定要採用哪些設定檔, 以下針對不同 shell 程式說明。
zsh
zsh 的設定檔執行順序如下:
-
不論是哪一種模式, 都會執行先執行
/etc/zshenv
檔, 例如我們將該檔案內容加上:
echo "/etc/zshenv read."
直接執行 zsh:
$ zsh /etc/zshenv read.
或是重新登入:
/etc/zshenv read. $
都會看到檔案中的
echo
顯示的 "/etc/zshenv read."。 -
每個
/etc
下的設定檔, 都有一個使用者私有的.
版本, 所以每個 zsh 也都會執行在使用者家目錄下的.zshenv
檔。如果在這個檔案裡面加入:
echo ".zshenv read."
不論是直接執行 zsh:
$ zsh /etc/zshenv read. .zshenv read. $
或是重新登入:
/etc/zshenv read. .zshenv read. $
都可以看到先執行
/etc/zshenv
接著執行.zshenv
。 -
若是 login shell, 會接著執行
/etc/zprofile
, 以及.zprofile
試著在該檔中個別加入對應的echo
指令, 可以發現直接執行bash
並不會執行這兩個設定檔:
$ zsh /etc/zshenv read. .zshenv read. $
但如果是重新登入, 因為是 login shell, 所以會執行這兩個設定檔:
/etc/zshenv read. .zshenv read. /etc/zprofile read. .zprofile read. $
-
接著若是 interactive shell, 就會再執行
/etc/zshrc
以及.zshrc
這一對檔案, 我們也利用同樣的方式加入echo
指令測試。直接執行zsh
結果如下:
$ zsh /etc/zshenv read. .zshenv read. /etc/zshrc read. .zshrc read. $
表示這是一個 interactive shell, 如果改成執行一個 shell 腳本:
$ zsh hello.sh /etc/zshenv read. .zshenv read. hello $
就不是 interactive shell, 也就不會執行
/etc/zshrc
與.zshrc
這對檔案了。重新登入則也會是 interactive shell:
/etc/zshenv read. .zshenv read. /etc/zprofile read. .zprofile read. /etc/zshrc read. .zshrc read. $
-
如果是 login shell, 還會再執行
/etc/zlogin
與zlogin
檔, 透過一樣的方式測試, 若直接執行zsh
:
$ zsh /etc/zshenv read. .zshenv read. /etc/zshrc read. .zshrc read. $
改成重新登入就不一樣了:
/etc/zshenv read. .zshenv read. /etc/zprofile read. .zprofile read. /etc/zshrc read. .zshrc read. /etc/zlogin read. .zlogin read. $
以上就是 zsh 執行個別設定檔的順序。
bash
bash 和 zsh 不大一樣, 詳細可參考這個圖解, 約略的順序如下:
-
如果不是 interactive shell, 就會執行
BASH_ENV
環境變數指定的檔案, 例如:
$ set | grep BASH_ENV BASH_ENV=.non_interactive_shell $ cat .non_interactive_shell echo ".non_interactive_shell read." $ cat hello.sh echo hello $ bash hello.sh .non_interactive_shell read. hello $
可以看到因為是執行腳本, 所以並不是 interactive shell, 會執行
BASH_ENV
環境變數指定的.non_interactive_shell
檔。如果單純執行bash
:
$ bash $
就不會執行
BASH_ENV
環境變數指定的.non_interactive_shell
檔 如果是 interactive shell, 但是 login shell, 就會先執行
/etc/profile
, 然後再執行.bash_profile
、.bash_login
、.profile
中第一個出現的檔案。如果是 interactive shell 也不是 login shell, 就會執行
/etc/bash.bashrc
檔。只要是 interactive shell, 最後還會執行
.bashrc
檔。
Top comments (0)