從 Bash 進階到 Z-shell,改進你的 shell 體驗。
Z-shell(Zsh)是一種 Bourne 式的互動式 POSIX shell,以其豐富的創新功能而著稱。Z-Shell 使用者經常會提及它的許多便利之處,讚譽它對效率的提高和豐富的自定義支援。
如果你剛接觸 Linux 或 Unix,但你的經驗足以讓你可以開啟終端並執行一些命令的話,那麼你可能使用的就是 Bash shell。Bash 可能是最具有代表意義的自由軟體 shell,部分是因為它具有的先進的功能,部分是因為它是大多數流行的 Linux 和 Unix 作業系統上的預設 shell。但是,隨著使用的次數越多,你可能會開始發現一些細節可能能夠做的更好。開源有一個眾所周知的地方,那就是選擇。所以,許多人選擇從 Bash “畢業”到 Z。
Shell 只是作業系統的介面。互動式 shell 程式允許你通過稱為標準輸入(stdin)的某個東西鍵入命令,並通過標準輸出(stdout)和標準錯誤(stderr)獲取輸出。有很多種 shell,如 Bash、Csh、Ksh、Tcsh、Dash 和 Zsh。每個都有其開發者所認為最適合於 Shell 的功能。而這些功能的好壞,則取決於終端使用者。
Zsh 具有互動式製表符補全、自動檔案搜尋、支援正規表示式、用於定義命令範圍的高階速記符,以及豐富的主題引擎等功能。這些功能也包含在你所熟悉的其它 Bourne 式 shell 環境中,這意味著,如果你已經了解並喜歡 Bash,那麼你也會熟悉 Zsh,除此以外,它還有更多的功能。你可能會認為它是一種 Bash++。
用你的包管理器安裝 Zsh。
在 Fedora、RHEL 和 CentOS 上:
$ sudo dnf install zsh
在 Ubuntu 和 Debian 上:
$ sudo apt install zsh
在 MacOS 上你可以使用 MacPorts 安裝它:
$ sudo port install zsh
或使用 Homebrew:
$ brew install zsh
在 Windows 上也可以執行 Zsh,但是只能在 Linux 層或類似 Linux 的層之上執行,例如 Windows 的 Linux 子系統(WSL)或 Cygwin。這類安裝超出了本文的範圍,因此請參考微軟的文件。
Zsh 不是終端模擬器。它是在終端模擬器中執行的 shell。因此,要啟動 Zsh,必須首先啟動一個終端視窗,例如 GNOME Terminal、Konsole、Terminal、iTerm2、rxvt 或你喜歡的其它終端。然後,你可以通過鍵入以下命令啟動 Zsh:
$ zsh
首次啟動 Zsh 時,會要求你選擇一些設定選項。這些都可以在以後更改,因此請按 1
繼續。
This is the Z Shell configuration function for new users, zsh-newuser-install.(q) Quit and do nothing.(0) Exit, creating the file ~/.zshrc(1) Continue to the main menu.
偏好設定分為四類,因此請從頂部開始。
1
使用預設選項,按 2
手動設定選項。cd
命令。要啟用這些額外選項之一,請輸入選項號並輸入 s
進行設定。請嘗試開啟所有選項以獲得完整的 Zsh 體驗。你可以稍後通過編輯 ~/.zshrc
取消設定它們。要完成設定,請按 0
。
剛開始,Zsh 的使用感受就像使用 Bash 一樣,這無疑是其眾多功能之一。例如,Bash 和 Tcsh 之間就存在嚴重的差異,因此如果你必須在工作中或在伺服器上使用 Bash,而 Zsh 就可以在家裡輕鬆嘗試和使用,這樣在 Bash 和 Zsh 之間輕鬆切換就是一種便利。
正是這些微小的差異使 Zsh 變得好用。首先,嘗試在沒有 cd
命令的情況下,將目錄更改為 Documents
資料夾。簡直太棒了,難以置信。如果你輸入的是目錄路徑而沒有進一步的指令,Zsh 會更改為該目錄:
% Documents% pwd/home/seth/Documents
而這會在 Bash 或任何其他普通 shell 中導致錯誤。但是 Zsh 卻根本不是普通的 shell,而這僅僅才是開始。
當你想使用普通 shell 程式查詢檔案時,可以使用 find
或 locate
命令。最起碼,你可以使用 ls -R
來遞回地列出一組目錄。Zsh 內建有允許它在當前目錄或任何其他子目錄中查詢檔案的功能。
例如,假設你有兩個名為 foo.txt
的檔案。一個位於你的當前目錄中,另一個位於名為 foo
的子目錄中。在 Bash Shell 中,你可以使用以下命令列出當前目錄中的檔案:
$ lsfoo.txt
你可以通過明確指明子目錄的路徑來列出另一個目錄:
$ ls foofoo.txt
要同時列出這兩者,你必須使用 -R
開關,並結合使用 grep
:
$ ls -R | grep foo.txtfoo.txtfoo.txt
但是在 Zsh 中,你可以使用 **
速記符號:
% ls **/foo.txtfoo.txtfoo.txt
你可以在任何命令中使用此語法,而不僅限於 ls
。想象一下在這樣的場景中提高的效率:將特定檔案型別從一組目錄中移動到單個位置、將文字片段串聯到一個檔案中,或對紀錄檔進行抽取。
製表符補全是 Bash 和其他一些 Shell 中的高階使用者功能,它變得司空見慣,席捲了 Unix 世界。Unix 使用者不再需要在輸入冗長而乏味的路徑時使用萬用字元(例如輸入 /h*/s*h/V*/SCS/sc*/comp*/t*/a*/*9/04/LS*boat*v
,比輸入 /home/seth/Videos/SCS/scenes/composite/takes/approved/109/04/LS_boat-port-cargo-mover.mkv
要容易得多)。相反,他們只要輸入足夠的唯一字串即可按 Tab
鍵。例如,如果你知道在系統的根目錄下只有一個以 h
開頭的目錄,則可以鍵入 /h
,然後單擊 Tab
。快速、簡單、高效。它還會確認路徑存在;如果 Tab
無法完成任何操作,則說明你在錯誤的位置或輸入了錯誤的路徑部分。
但是,如果你有許多目錄有五個或更多相同的首字母,Tab
會堅決拒絕進行補全。儘管在大多數現代終端中,它將(至少會)顯示阻止其進行猜測你的意思的檔案,但通常需要按兩次 Tab
鍵才能顯示它們。因此,製表符補全通常會變成來回按下鍵盤上字母和製表符,以至於你好像在接受鋼琴獨奏會的訓練。
Zsh 通過迴圈可能的補全來解決這個小問題。如果鍵入 ls ~/D
並按 Tab
,則 Zsh 首先使用 Documents
來完成命令;如果再次按 Tab
,它將提供 Downloads
,依此類推,直到找到所需的選項。
在 Zsh 中,萬用字元的行為不同於 Bash 中使用者所習慣的行為。首先,可以對其進行修改。例如,如果要列出當前目錄中的所有資料夾,則可以使用修改後的萬用字元:
% lsdir0 dir1 dir2 file0 file1% ls *(/)dir0 dir1 dir2
在此範例中,(/)
限定了萬用字元的結果,因此 Zsh 僅顯示目錄。要僅列出檔案,請使用 (.)
。要列出符號連結,請使用 (@)
。要列出可執行檔案,請使用 (*)
。
% ls ~/bin/*(*)fop exify tt
Zsh 不僅僅知道檔案型別。它也可以使用相同的萬用字元修飾符約定根據修改時間列出。例如,如果要查詢在過去八個小時內修改的檔案,請使用 mh
修飾符(即 “modified hours” 的縮寫)和小時的負整數:
% ls ~/Documents/*(mh-8)cal.org game.org home.org
要查詢超過(例如)兩天前修改過的檔案,修飾符更改為 md
(即 “modified day” 的縮寫),並帶上天數的正整數:
% ls ~/Documents/*(+2)holiday.org
萬用字元修飾符和限定符還可以做很多事情,因此,請閱讀 當你切換到新的 shell 時,這些小異常可能會使你感到沮喪。使用 Zsh 時會遇到的問題不多(體驗過 Zsh 後切換回 Bash 的可能遇到更多),但是當它們發生時,請保持鎮定且坦率。嚴格遵守 POSIX 的情況很少會出錯,但是如果失敗了,請查詢問題以解決並繼續。對於許多在工作中困在一個 shell 上而在家中困在另一個 shell 上的使用者來說,hyperpolyglot.org 已被證明其是無價的。 在我的下一篇 Zsh 文章中,我將向你展示如何安裝主題和外掛以客製化你的 Z-Shell 甚至 Z-ier。% scp IMG_*.JPG [email protected]:~/www/ph\*/\*19/09/14