章節概覽#
本章探討 Linux 系統中的使用者環境 (User Environments),重點在於 shell 啟動檔案(startup files)的設計與管理。這些檔案(又稱 dot files,因為檔名以 . 開頭)決定了使用者登入後 shell 和互動程式的預設行為。
隨著時間推移,啟動檔案容易累積不必要的環境變數和測試,導致各種問題。本章說明如何正確建立、組織和維護這些檔案。
13.1 建立啟動檔案的準則#
設計啟動檔案時,應以使用者為核心考量。如果你是機器上唯一的使用者,錯誤容易修復;但若檔案會被其他使用者共用(例如作為新使用者的預設值),則需格外謹慎。
建立啟動檔案的兩個基本目標:
- Simplicity(簡潔):保持啟動檔案數量少、內容精簡,容易修改且不易出錯。每多一個項目就多一個潛在的故障點。
- Readability(可讀性):在檔案中加入充分的註解,讓使用者能清楚了解每個部分的功能。
13.2 何時修改啟動檔案#
在修改啟動檔案之前,先問自己是否真的有必要。合理的修改理由包括:
- 想要變更預設的 prompt
- 需要為本地安裝的關鍵軟體做調整(但優先考慮使用 wrapper script)
- 現有的啟動檔案已經損壞
如果你的 Linux 發行版一切運作正常,修改時要特別小心。預設的啟動檔案可能與
/etc中的其他檔案有互動關係。
13.3 Shell 啟動檔案的要素#
13.3.1 Command Path#
Command path 是啟動檔案中最重要的部分。路徑至少應包含以下目錄(按此順序):
/usr/local/bin
/usr/bin
/bin這個順序確保 /usr/local 中的自訂程式可以覆蓋系統預設版本。
許多使用者會建立自己的 bin 目錄來存放腳本,可以將其加到路徑最前面:
$HOME/bin較新的慣例是將個人二進位檔放在
$HOME/.local/bin。
如果需要系統管理工具(如 sysctl、fdisk、lsmod),可以加入 sbin 目錄:
/usr/local/sbin
/usr/sbin
/sbin不要在路徑中加入
.(當前目錄)。這是安全風險——攻擊者可以在常見目錄中放置名為ls的木馬程式。即使放在路徑末端,也可能被利用打字錯誤(如s1或ks)來攻擊。
13.3.2 Manual Page Path#
傳統上 MANPATH 環境變數用來設定手冊頁路徑,但不建議手動設定,因為這會覆蓋 /etc/manpath.config 中的系統預設值。
13.3.3 Prompt#
有經驗的使用者傾向避免冗長、複雜的 prompt。應根據實際需求選擇包含的資訊。
bash 中常用的 prompt 特殊字元:
\u— 使用者名稱\h— 主機名稱(短格式)\!— 歷史記錄編號\w— 當前工作目錄(\W只顯示最後一層)\$— 一般使用者顯示$,root 顯示#
簡單的 prompt 設定範例:
PS1='\u\$ '避免在 prompt 中使用對 shell 有特殊意義的字元,如
{ } = & < >。特別注意>字元——如果不小心複製貼上 prompt 內容,可能會因為重新導向而覆蓋檔案。
13.3.4 Aliases#
Aliases 是 shell 的字串替換功能,可以在執行命令前將一個字串替換為另一個。雖然方便,但有幾個缺點:
- 難以操作引數
- 令人困惑——
which命令可以告訴你某個東西是 alias,但不會告訴你它的定義位置 - 在 subshell 和非互動式 shell 中無法使用,也不會傳遞給子 shell
定義 alias 時的經典錯誤是為現有命令添加額外引數,例如
alias ls='ls -F'。這會使移除-F參數變得困難,對不了解預設引數已被更改的使用者可能造成嚴重後果。
建議盡量使用 shell function 或獨立的 shell script 來取代 alias。
13.3.5 Permissions Mask#
使用 shell 內建的 umask 命令設定預設權限。兩個合理的選擇:
- 077 — 最嚴格,不讓其他使用者存取新檔案。適合多使用者系統中重視隱私的環境。
- 022 — 讓其他使用者可以讀取新檔案。適合單一使用者系統,因為以 pseudo-user 身分執行的 daemon 需要能存取檔案。
某些應用程式(尤其是郵件程式)會自行覆蓋 umask 為 077,因為它們認為自己的檔案只應由檔案擁有者存取。
13.4 啟動檔案的順序與範例#
13.4.1 bash Shell#
在 bash 中,可以使用的啟動檔案包括 .bash_profile、.profile、.bash_login 和 .bashrc。要理解應該使用哪個檔案,需要先了解 bash shell 的兩種類型。
Login Shell#
Login shell 是使用者首次登入系統時取得的 shell(例如透過 /bin/login 或 SSH)。判斷方法:
echo $0如果第一個字元是 -,就是 login shell。
Login shell 啟動時會依序執行:
/etc/profile- 使用者的
.bash_profile、.bash_login、.profile(只執行找到的第一個)
Non-Login Shell#
Non-login shell 是登入後額外啟動的互動式 shell。視窗系統的終端程式(如 xterm、GNOME Terminal)預設啟動的就是 non-login shell。
Non-login shell 啟動時會執行:
/etc/bash.bashrc- 使用者的
.bashrc
兩種 Shell 的歷史原因#
早期使用者透過終端以 login shell 登入,再透過視窗系統啟動 non-login subshell。為避免重複設定環境,login shell 負責完整設定(PATH、環境變數等),non-login shell 只負責輕量的設定(如 alias)。
現代桌面使用者通常透過圖形化 display manager 登入,大多數 display manager 會啟動一個非互動式的 login shell。因此建議將所有環境設定放在 .bashrc 中,並讓 .bash_profile 指向它。
.bashrc 範例#
# Command path.
PATH=/usr/local/bin:/usr/bin:/bin:/usr/games
PATH=$HOME/bin:$PATH
# PS1 is the regular prompt.
PS1='\u\$ '
# EDITOR and VISUAL determine the editor that programs such as less
# and mail clients invoke when asked to edit a file.
EDITOR=vi
VISUAL=vi
# PAGER is the default text file viewer for programs such as man.
PAGER=less
# These are some handy options for less.
LESS=meiX
# You must export environment variables.
export PATH EDITOR VISUAL PAGER LESS
# By default, give other users read-only access to most new files.
umask 022可以透過 symbolic link 或以下 one-liner 讓 .bash_profile 指向 .bashrc:
. $HOME/.bashrc區分 Login 和 Interactive Shell#
如果需要在 .bashrc 中區分 login 和 non-login shell,可以檢查 $- 變數中的 i 字元:
case $- in
*i*) # interactive commands go here
;;
*) # non-interactive commands go here
;;
esac13.4.2 tcsh Shell#
tcsh 是 csh 的增強版,提供命令列編輯和檔名補全等功能。tcsh 不區分 login 和 non-login shell——啟動時先尋找 .tcshrc,找不到則使用 .cshrc。
建議使用 .cshrc 而非 .tcshrc,以確保在遇到傳統 csh 的系統上也能相容。
.cshrc 範例#
# Command path.
setenv PATH $HOME/bin:/usr/local/bin:/usr/bin:/bin
# EDITOR and VISUAL
setenv EDITOR vi
setenv VISUAL vi
# PAGER
setenv PAGER less
# Options for less.
setenv LESS meiX
# Default permissions.
umask 022
# Customize the prompt.
set prompt="%m%% "13.5 預設使用者設定#
測試啟動檔案的最佳方式是建立一個新的測試使用者,使用空白的 home 目錄,從頭撰寫啟動檔案。確認一切正常後,再建立第二個測試使用者來驗證。
13.5.1 Shell Defaults#
新使用者的預設 shell 應為 bash,原因包括:
- 使用者用來互動的 shell 與撰寫腳本的 shell 一致
- bash 是 Linux 發行版的預設 shell
- bash 使用 GNU readline 函式庫來接受輸入,介面與許多其他工具一致
- bash 提供良好的 I/O 重新導向和 file handle 控制
還有許多其他 shell 可選擇(rc、ksh、zsh、es、fish 等)。其中 zsh 和 fish 在尋找替代 shell 的新使用者中相當受歡迎。使用者可以透過
chsh命令自行變更 shell。
13.5.2 Editor#
傳統的預設編輯器是 vi 或 emacs,因為它們幾乎在所有 Unix 系統上都存在。Linux 發行版通常將 nano 設為預設,因為對初學者更友善。
在 shell 啟動檔案中避免使用大型的編輯器啟動檔。可以在 .exrc 中設定小型選項(例如讓 vi 顯示匹配括號的 showmatch),但避免大幅改變編輯器的行為或外觀。
13.5.3 Pager#
Pager 是一次顯示一頁文字的程式(如 less)。將 PAGER 環境變數設為 less 是合理的預設值。
13.6 啟動檔案的常見陷阱#
在啟動檔案中應避免以下做法:
- 不要放入任何圖形化命令——不是所有 shell 都在圖形環境中執行
- 不要設定
DISPLAY環境變數——可能導致圖形化 session 異常 - 不要設定終端類型 (terminal type)
- 不要省略描述性註解
- 不要在啟動檔案中執行會輸出到標準輸出的命令
- 不要在啟動檔案中設定
LD_LIBRARY_PATH
13.7 進階啟動主題#
本書不涵蓋視窗環境 (windowing environment) 的啟動檔案,因為這是一個龐大的主題。Display manager 有自己的啟動檔案(如 .xsession、.xinitrc),加上 GNOME 和 KDE 相關的各種組合,選擇繁多。
保持 shell 啟動檔案簡潔的原則同樣適用於 GUI 啟動檔案。事實上,你很可能完全不需要修改 GUI 啟動檔案。