前言
Shell 不僅能處理互動式指令,也內建了程式語言的功能。藉由命令列腳本(Shell Script),使用者可以將複雜的操作寫成程式碼,並在需要時重複呼叫。
透過 Unix 的組合哲學,我們不需要為每項任務重寫新的程式,而是能直接串接現現有的工具,用相對省力的方式達成目標。
命令列腳本的用途
以下情境適合使用命令列腳本(Shell Script):
- 在 Unix 系統命令列中執行的任務。
- 呼叫現有的命令列工具。
- 用來自動化重複性高的工作。
- 對程式執行速度與效能要求不高的情境。
現行的桌面環境以 Windows 為大宗,較難直接感受到命令列腳本的優勢。但在許多非桌面環境中,包括伺服器、高效能運算主機(HPC)、嵌入式系統等,大多都是 Unix / Linux 系統的天下,這時就能利用命令列腳本來完成各種複雜的任務。
命令列腳本的本質就是「自動化」。只要能在 Unix 命令列環境中完成的操作,都有機會轉化為腳本。如果再搭配 Cron 等定時排程工具,就能實現完全自動化運行。
Shell 的核心語法非常精簡,加上它是直譯式語言,開發速度極快。此外,Shell 本身就內建偵錯功能,不需要依賴大型 IDE 輔助,只要用 nano 這類輕量文字編輯器就能直接撰寫,甚至在沒有圖形介面的純文字環境中也能輕鬆開發。
命令列腳本的種類
Bourne Shell
目前最主流的 Shell 腳本家族,現今常見的 Bash 和 Zsh 都是 Bourne Shell 的延伸。
雖然 Bash 相當普及,但仍建議先從相容性最高的 POSIX sh 學起,避免一開始就依賴 Bash 或 Zsh 的特有語法。
C Shell
主要用於早期的 BSD 系統,包括 csh 與 tcsh。目前 C Shell 在實務上已較少使用,除非有特定歷史需求,否則不需要特別學習。
新興 Shell
這類 Shell 採用了不相容於 Bourne Shell 與 C Shell 的全新語法,例如 Fish。
由於大部分伺服器系統不會預裝這些新興 Shell,導致寫好的腳本移植性較低。因此在學習投資報酬率的考量下,實務上並不建議用它們來編寫腳本。
命令列腳本的相容性議題
雖然 POSIX sh 的語法相當穩定,但不同作業系統間的指令參數差異,才是跨平台腳本難以完美相容的主因。
現行指令參數主要分為 GNU 與 BSD 兩種風格。若追求高相容性,應盡量避免使用 GNU 特有的擴充功能(如雙連字號開頭的長參數 --long-options),並優先採用各系統通用的基本參數。
驗證相容性的最佳實踐
- 多環境實地測試:在虛擬機器中分別安裝 Linux 與 BSD 系統進行驗證。
- 嚴格環境建置:特別是開源專案,建議在 Alpine Linux 和 FreeBSD 等嚴格的 POSIX 環境中測試。
- 查閱線上手冊:透過終端機或網路查閱各系統的
man page,核對參數的支援度與行為差異。
命令列腳本的替代品
命令列腳本雖然方便,但並非唯一的選擇。如果不想專門學習 Shell Script,也可以使用其他高階腳本語言來替代。只要該語言能夠與系統的命令列工具溝通,就能用來取代命令列腳本。在 Unix / Linux 系統上,最適合的替代語言是 Perl 或 Python。
Perl 最初就是為了改進 Shell、sed、awk 等工具的不足而誕生的語言,因此非常適合用來編寫自動化腳本。雖然 Perl 並不屬於 POSIX 標準的一部分,但絕大多數的 Unix 系統都會預裝 Perl。
相對來說,Python 則是近年來極為熱門的程式語言,廣泛應用於各種領域,包括自動化腳本。由於 Perl 和 Python 在功能上有許多重疊之處,而 Python 的程式碼又相對直覺易讀,因此近年來許多系統使用者會直接選擇用 Python 來取代 Perl。
不過,如果單純以「操作命令列工具」來看,命令列腳本語法絕對是最精簡的。本節提到的兩款程式語言,僅作為不想學習 Shell 語法、卻又有自動化需求時的替代方案。
結語
本文探討了命令列腳本(Shell Script)的使用時機與相容性等議題。相信讀完本文後,讀者們都能清楚了解自己學習與撰寫命令列腳本的核心動機與價值。