Zsh vs. Bash不完全对比解析,zsh是一种更强大的被成为“终极”的Shell
?
https://www.zhihu.com/question/21418449
?
?
Mort | Zsh vs. Bash:不完全對(duì)比解析(1)
2014-10-07 ?bdpqlxzZsh和Bash,究竟有何不同
已經(jīng)有不少人寫過類似“為什么Zsh比Bash好”“為什么Zsh比* shell好”的文章了,講解如何配置Zsh或折騰各種oh-my-zsh主題的教程也是一搜一大籮,但是卻極少看到Zsh和Bash這兩個(gè)Shell作為腳本語言時(shí)的具體差異比較。那么,這里就是一篇,從語言特性的角度上簡(jiǎn)單整理了兩者一些細(xì)微的不兼容之處,供編寫可移植Shell腳本時(shí)參考。(僅僅是從我自己過去的經(jīng)驗(yàn)教訓(xùn)中總結(jié)出來的,所以應(yīng)該也是不完全的。)
開始之前:理解Zsh的仿真模式(emulation mode)
一種流行的說法是,Zsh是與Bash兼容的。這種說法既對(duì),也不對(duì),因?yàn)閆sh本身作為一種腳本語言,是與Bash不兼容的。符合Bash規(guī)范的腳本無法保證被Zsh解釋器正確執(zhí)行。但是,Zsh實(shí)現(xiàn)中包含了一個(gè)屌炸天的仿真模式(emulation mode),支持對(duì)兩種主流的Bourne衍生版shell(bash、ksh)和C shell的仿真(csh的支持并不完整)。在Bash的仿真模式下,可以使用與Bash相同的語法和命令集合,從而達(dá)到近乎完全兼容的目的。為了激活對(duì)Bash的仿真,需要顯式執(zhí)行:
$ emulate bash等效于:
$ emulate shZsh是不會(huì)根據(jù)文件開頭的shebang(如#!/bin/sh和#!/bin/bash)自動(dòng)采取兼容模式來解釋腳本的,因此,要讓Zsh解釋執(zhí)行一個(gè)其他Shell的腳本,你仍然必須手動(dòng)emulate sh或者emulate ksh,告訴Zsh對(duì)何種Shell進(jìn)行仿真。
那么,Zsh究竟在何時(shí)能夠自動(dòng)仿真某種Shell呢?
對(duì)于如今的絕大部分GNU/Linux(Debian系除外)和Mac OS X用戶來說,系統(tǒng)默認(rèn)的/bin/sh指向的是bash:
$ file /bin/sh /bin/sh: symbolic link to `bash'不妨試試用zsh來取代bash作為系統(tǒng)的/bin/sh:
# ln -sf /bin/zsh /bin/sh所有的Bash腳本仍然能夠正確執(zhí)行,因?yàn)閆sh在作為/bin/sh存在時(shí),能夠自動(dòng)采取其相應(yīng)的兼容模式(emulate sh)來執(zhí)行命令。也許正是因?yàn)檫@個(gè)理由,Grml直接選擇了Zsh作為它的/bin/sh,對(duì)現(xiàn)有的Bash腳本能做到近乎完美的兼容。
無關(guān)主題:關(guān)于/bin/sh和shebang的可移植性
說到/bin/sh,就不得不提一下,在Zsh的語境下,sh指的是大多數(shù)GNU/Linux發(fā)行版上/bin/sh默認(rèn)指向的bash,或者至少是一個(gè)Bash的子集(若并非全部GNU Bash的最新特性都被實(shí)現(xiàn)的話),而非指POSIX shell。因此,Zsh中的emulate sh可以被用來對(duì)Bash腳本進(jìn)行仿真。
眾所周知,Debian的默認(rèn)/bin/sh是 dash(Debian Almquist shell),這是一個(gè)純粹POSIX shell兼容的實(shí)現(xiàn),基本上你要的bash和ksh里的那些高級(jí)特性它都沒有。“如果你在一個(gè)#!/bin/sh腳本中用到了非POSIX shell的東西,說明你的腳本寫得是錯(cuò)的,不關(guān)我們發(fā)行版的事情。”Debian開發(fā)者們?cè)诎涯J(rèn)的/bin/sh換成dash,導(dǎo)致一些腳本出錯(cuò)時(shí)這樣宣稱道。當(dāng)然,我們應(yīng)該繼續(xù)假裝與POSIX shell標(biāo)準(zhǔn)保持兼容是一件重要的事情,即使現(xiàn)在大家都已經(jīng)用上了更高級(jí)的shell。
因?yàn)橛蟹荊NU的Unix,和Debian GNU/Linux這類發(fā)行版的存在,你不能夠假設(shè)系統(tǒng)的/bin/sh總是GNU Bash,也不應(yīng)該把#!/bin/sh用作一個(gè)Bash腳本的shebang(——除非你愿意放棄你手頭Shell的高級(jí)特性,寫只與POSIX shell兼容的腳本)。如果想要這個(gè)腳本能夠被方便地移植的話,應(yīng)指定其依賴的具體Shell解釋器:
#!/usr/bin/env bash這樣系統(tǒng)才能夠總是使用正確的Shell來運(yùn)行腳本。
(當(dāng)然,顯式地調(diào)用bash命令來執(zhí)行腳本,shebang怎樣寫就無所謂了)
echo命令 / 字符串轉(zhuǎn)義
Zsh比之于Bash,可能最容易被注意到的一點(diǎn)不同是,Zsh中的echo和printf是內(nèi)置的命令。
$ which echo echo: shell built-in command$ which printf printf: shell built-in commandBash中的echo和printf同樣是內(nèi)置命令:
$ type echo echo is a shell builtin$ type printf echo is a shell builtin感謝讀者提醒,在Bash中不能通過which來確定一個(gè)命令是否為外部命令,因?yàn)閣hich本身并不是Bash中的內(nèi)置命令。which在Zsh中是一個(gè)內(nèi)置命令。
Zsh內(nèi)置的echo命令,與我們以前在GNU Bash中常見的echo命令,使用方式是不兼容的。
首先,請(qǐng)看Bash:
$ echo \ $ echo \\\\我們知道,因?yàn)檫@里傳遞給echo的只是一個(gè)字符串(允許使用反斜杠\轉(zhuǎn)義),所以不加引號(hào)與加上雙引號(hào)是等價(jià)的。Bash輸出了我們預(yù)想中的結(jié)果:每?jī)蓚€(gè)連續(xù)的\轉(zhuǎn)義成一個(gè)\字符輸出,最終2個(gè)變1個(gè),4個(gè)變2個(gè)。沒有任何驚奇之處。
你能猜到Zsh的輸出結(jié)果么?
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
(゜Д゜*)
解釋稍后。
我們還知道,要想避免一個(gè)字符串被反斜杠轉(zhuǎn)義,可以把它放進(jìn)單引號(hào)。正如我們?cè)贐ash中所清楚看到的這樣,所有的反斜杠都照原樣輸出:
$ echo '\\' \ $ echo '\\\\' \\\再一次,你能猜到Zsh的輸出結(jié)果么?
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
((((((゜Д゜*))))))))))))
這個(gè)解釋是這樣的:在前一種不加引號(hào)(或者加了雙引號(hào))的情形下,傳遞給echo內(nèi)部命令的字符串將首先被轉(zhuǎn)義,echo \\中的\\被轉(zhuǎn)義成\,echo \\\\中的\\\\被轉(zhuǎn)義成\\。然后,在echo這個(gè)內(nèi)部命令輸出到終端的時(shí)候,它還要把這個(gè)東西再轉(zhuǎn)義一遍,一個(gè)單獨(dú)的\沒法轉(zhuǎn)義,所以仍然是作為\輸出;連續(xù)的\\被轉(zhuǎn)義成\,所以輸出就是\。因此,echo \\和echo \\\\的輸出相同,都是\。
為了讓Zsh中echo的輸出不被轉(zhuǎn)義,需要顯式地指明-E選項(xiàng):
$ echo -E \ $ echo -E \\\\于是,我們也就知道在后一種加單引號(hào)的情形下,如何得到與原字符串完全相同的輸出了:
$ echo -E '\\' \ $ echo -E '\\\\' \\\而Bash的echo默認(rèn)就是不對(duì)輸出進(jìn)行轉(zhuǎn)義的,若要得到轉(zhuǎn)義的效果,需顯式地指定-e選項(xiàng)。Bash和Zsh中echo命令用法的不兼容,在這里體現(xiàn)出來了。
變量的自動(dòng)分字(word splitting)
在Bash中,你可以通過調(diào)用外部命令echo輸出一個(gè)字符串:
echo $text我們知道,Bash會(huì)對(duì)傳遞給命令的字符串進(jìn)行分字(根據(jù)空格或換行符),然后作為多個(gè)參數(shù)傳給echo。當(dāng)然,作為分隔符的換行,在最終輸出時(shí)就被抹掉了。于是,更好的習(xí)慣是把變量名放在雙引號(hào)中,把它作為一個(gè)字符串傳遞,這樣就可以保留文本中的換行符,將其原樣輸出。
echo "$text"在Zsh中,你不需要通過雙引號(hào)來告訴解釋器“$text是一個(gè)字符串”。解釋器不會(huì)把它轉(zhuǎn)換成一個(gè)由空格或者\(yùn)n分隔的參數(shù)列表或者別的什么。所以,沒有Bash中的trick,直接echo $text就可以保留換行符。但是,如前一節(jié)所說,我們需要一個(gè)多余的工作來保證輸出的是未轉(zhuǎn)義的原始文本,那就是-E選項(xiàng):
echo -E $text從這里我們看到,Zsh中的變量在傳遞給命令時(shí)是不會(huì)被自動(dòng)切分成words然后以多個(gè)參數(shù)的形式存在的。它仍然保持為一個(gè)量。這是它與傳統(tǒng)的Bourne衍生shell(ksh、bash)的一個(gè)重要不兼容之處。這是Zsh的特性,而不是一個(gè)bug。
通配符展開(globbing)
通配符展開(globbing)也許是Unix shell中最為實(shí)用化的功能之一。比起正則表達(dá)式,它的功能相當(dāng)有限,不過它的確能滿足大部分時(shí)候的需求:依據(jù)固定的前綴或后綴匹配文件。需要更復(fù)雜模式的時(shí)候其實(shí)是很少見的,至少在文件的命名和查找上。
Bash和Zsh對(duì)通配符展開的處理方式有何不同呢?舉個(gè)例子,假如我們想要列舉出當(dāng)前目錄下所有的.markdown文件,但實(shí)際上又不存在這樣的文件。在Zsh中:(注意到這里使用了內(nèi)置的echo,因?yàn)槲覀儠簳r(shí)還不想用到外部的系統(tǒng)命令)
$ echo *.markdown zsh: no matches found: *.markdownBash中:
$ echo *.markdown *.markdownZsh因?yàn)橥ㄅ浞归_失敗而報(bào)錯(cuò);而Bash在通配符展開失敗時(shí),會(huì)放棄把它作為通配符展開、直接把它當(dāng)做字面量返回。看起來,Zsh的處理方式更優(yōu)雅,因?yàn)檫@樣你就可以知道這個(gè)通配符確實(shí)無法展開;而在Bash中,你很難知道究竟是不存在這樣的文件,還是存在一個(gè)文件名為'*.markdown'的文件。
接下來就是不那么和諧的方面了。
在Zsh中,用ls查看當(dāng)然還是報(bào)錯(cuò):
$ ls *.markdown zsh: no matches found: *.markdownBash,這時(shí)候調(diào)用ls也會(huì)報(bào)錯(cuò)。因?yàn)楫?dāng)前目錄下沒有.markdown后綴的文件,通配符展開失敗后變成字面的'*.markdown',這個(gè)文件自然也不可能存在,所以外部命令ls報(bào)錯(cuò):
$ ls *.markdown ls: cannot access *.markdown: No such file or directory同樣是錯(cuò)誤,差別在哪里?對(duì)于Zsh,這是一個(gè)語言級(jí)別的錯(cuò)誤;對(duì)于Bash,這是一個(gè)外部命令執(zhí)行的錯(cuò)誤。這件差別很重要,因?yàn)樗馕吨笳呖梢员惠p易地catch,而前者不能。
想象一個(gè)常見的命令式編程語言,Java或者Python。你可以用try...catch或類似的語言結(jié)構(gòu)來捕獲運(yùn)行時(shí)的異常,比較優(yōu)雅地處理無法預(yù)料的錯(cuò)誤。Shell當(dāng)然沒有通用的異常機(jī)制,但是,你可以通過檢測(cè)某一段命令的返回值來模擬捕獲運(yùn)行時(shí)的錯(cuò)誤。例如,在Bash里可以這樣:
$ if ls *.markdown &>/dev/null; then :; else echo $?; fi 2于是,在通配符展開失敗的情形下,我們也能輕易地把外部命令的錯(cuò)誤輸出重定向到/dev/null,然后根據(jù)返回的錯(cuò)誤碼執(zhí)行后續(xù)的操作。
不過在Zsh中,這個(gè)來自Zsh解釋器自身的錯(cuò)誤輸出卻無法被重定向:
$ if ls *.markdown &>/dev/null; then :; else echo $?; fi zsh: no matches found: *.markdown 1大部分時(shí)候,我們并不想看到這些丑陋多余的錯(cuò)誤輸出,我們期望程序能完全捕獲這些錯(cuò)誤,然后完成它該完成的工作。但這也許是一種正常的行為。理由是,在程序語言里,syntax error一般是無法簡(jiǎn)單地由用戶在運(yùn)行階段自行catch的,這個(gè)報(bào)錯(cuò)工作將直接由解釋器來完成。除非,當(dāng)然,除非我們用了邪惡的eval。
$ if eval "ls *.markdown" &>/dev/null; then :; else echo $?; fi 1Eval is evil. 但在Zsh中捕獲這樣的錯(cuò)誤,似乎沒有更好的辦法了。必須這么做的原因就是:Zsh中,通配符展開失敗是一個(gè)語法錯(cuò)誤。而在Bash中則不是。
基于上述理由,依賴于Bash中通配符匹配失敗而直接把"*"當(dāng)作字面量傳遞給命令的寫法,在Zsh中是無法正常運(yùn)行的。例如,在Bash中你可以:(雖然在大部分情況下能用,但顯然不加引號(hào)是不科學(xué)的)
$ find /usr/share/git -name *.el因?yàn)閆sh不會(huì)在glob擴(kuò)展失敗后自動(dòng)把"*"當(dāng)成字面量,而是直接報(bào)錯(cuò)終止運(yùn)行,所以在Zsh中你必須給"*.el"加上引號(hào),來避免這種擴(kuò)展:
$ find /usr/share/git -name "*.el"字符串比較
在Bash中判斷兩個(gè)字符串是否相等:
[ "$foo" = "$bar" ]或與之等效的(現(xiàn)代編程語言中更常見的==比較運(yùn)算符):
[ "$foo" == "$bar" ]注意等號(hào)左右必須加空格,變量名一定要放在雙引號(hào)中。(寫過Shell的都知道這些規(guī)則的重要性)
在條件判斷的語法上,Zsh基本和Bash相同,沒有什么改進(jìn)。除了它的解釋器想得太多,以至于不小心把==當(dāng)做了一個(gè)別的東西:
$ [ foo == bar ]; echo $? zsh: = not found要想使用我們最喜歡的==,只有把它用引號(hào)給保護(hù)起來,不讓解釋器做多余的解析:
$ [ foo "==" bar ]; echo $? 1所以,為了少打幾個(gè)字符,還是老老實(shí)實(shí)用更省事的=吧。
數(shù)組
同樣用一個(gè)簡(jiǎn)單的例子來說明。Bash:
array=(alpha bravo charlie delta) echo $array echo ${array[*]} echo ${#array[*]} for ((i=0; i < ${#array[*]}; i++)); doecho ${array[$i]} done輸出:
alpha alpha bravo charlie delta 4 alpha bravo charlie delta很容易看到,Bash的數(shù)組下標(biāo)是從0開始的。$array取得的實(shí)際上是數(shù)組的第一個(gè)元素的值,也就是${array[0]}(這些行為和C有點(diǎn)像)。要想取得整個(gè)數(shù)組的值,必須使用${array[*]}或${array[@]},因此,獲取數(shù)組的長(zhǎng)度可以使用${#array[*]}。在Bash中,必須記得在訪問數(shù)組元素時(shí)給整個(gè)數(shù)組名連同下標(biāo)加上花括號(hào),比如,${array[*]}不能寫成$array[*],否則解釋器會(huì)首先把$array當(dāng)作一個(gè)變量來處理。
再來看這段Zsh:
array=(alpha bravo charlie delta) echo $array echo $array[*] echo $#array for ((i=1; i <= $#array[*]; i++)); doecho $array[$i] done輸出:
alpha bravo charlie delta alpha bravo charlie delta 4 alpha bravo charlie delta在Zsh中,$array和$array[*]一樣,可以用來取得整個(gè)數(shù)組的值。因此獲取數(shù)組的長(zhǎng)度可直接用$#array。
Zsh的默認(rèn)數(shù)組下標(biāo)是從1而不是0開始的,這點(diǎn)更像C shell。(雖然一直無法理解一個(gè)名字叫C的shell為何會(huì)采用1作為數(shù)組下標(biāo)開始這種奇葩設(shè)定)
最后,Zsh不需要借助花括號(hào)來訪問數(shù)組元素,因此Bash中必需的花括號(hào)都被略去了。
關(guān)聯(lián)數(shù)組
Bash 4.0+和Zsh中都提供了對(duì)類似AWK關(guān)聯(lián)數(shù)組的支持。
declare -A array array[mort]=foo和普通的數(shù)組一樣,在Bash中,必須顯式地借助花括號(hào)來訪問一個(gè)數(shù)組元素:
echo ${array[mort]}而Zsh中則沒有必要:
echo $array[mort]說到這里,我們注意到Zsh有一個(gè)不同尋常的特性:支持使用方括號(hào)進(jìn)行更復(fù)雜的globbing,array[mort]這樣的寫法事實(shí)上會(huì)造成二義性:究竟是取array這個(gè)關(guān)聯(lián)數(shù)組以mort為key的元素值呢,還是以通配符展開的方式匹配當(dāng)前目錄下以"array"開頭,以"m"、"o"、"r"或"t"任一字符結(jié)尾的文件名呢?
在array[mort]=作為命令開始的情況下,不存在歧義,這是一個(gè)對(duì)關(guān)聯(lián)數(shù)組的賦值操作。在前面帶有$的情況下,Zsh會(huì)自動(dòng)把$array[mort]識(shí)別成取關(guān)聯(lián)數(shù)組的值,這也沒有太大問題。問題出在它存在于命令中間,卻又不帶$的情況,比如:
read -r -d '' array[mort] << 'EOF' hello world EOF我們的本意是把這個(gè)heredoc賦值給array[mort]數(shù)組元素。在Bash中,這是完全合法的。然而,在Zsh中,解釋器會(huì)首先試圖對(duì)"array[mort]"這個(gè)模式進(jìn)行g(shù)lob展開,如果當(dāng)前目錄下沒有符合該模式的文件,當(dāng)然就會(huì)報(bào)出一個(gè)語法錯(cuò)誤:
zsh: no matches found: array[mort]這是一件很傻的事情,為了讓這段腳本能夠被Zsh解釋器正確執(zhí)行,我們需要把a(bǔ)rray[mort]放在引號(hào)中以防止被展開:
read -r -d '' 'array[mort]' << 'EOF' hello world EOF這是Zsh在擴(kuò)展了一些強(qiáng)大功能的同時(shí)帶來的不便之處(或者說破壞了現(xiàn)有腳本兼容性的安全隱患,又或者是讓解釋器混亂的pitfalls)。
順便說一句,用Rake構(gòu)建過項(xiàng)目的Rails程序員都知道,有些時(shí)候需要在命令行下通過方括號(hào)給rake傳遞參數(shù)值,如:
$ rake seeder:seed[100]Zsh這個(gè)對(duì)方括號(hào)展開的特性確實(shí)很不方便。如果不想每次都用單引號(hào)把參數(shù)括起來,可以完全禁止Zsh對(duì)某條命令后面的參數(shù)進(jìn)行g(shù)lob擴(kuò)展:(~/.zshrc)
alias rake="noglob rake"嗯,對(duì)于rake命令來說,glob擴(kuò)展基本是沒有用的。你可以關(guān)掉它。
分號(hào)與空語句
雖然有點(diǎn)無聊,但還是想提一下:Bash不允許語句塊中使用空語句,最小化的語句是一個(gè)noop命令(:);而Zsh允許空語句。
剛開始寫B(tài)ash的時(shí)候,總是記不得什么時(shí)候該加分號(hào)什么時(shí)候不該加。比如
if [ 1 ] then: fi如果放在一行里寫,應(yīng)該是
if [ 1 ]; then :; fithen后面是不能接分號(hào)的,如果寫成
if [ 1 ]; then; :; fi就會(huì)報(bào)錯(cuò):
bash: syntax error near unexpected token `;'解釋是:then表示一個(gè)代碼段的開始,fi表示結(jié)束,這中間的內(nèi)容必須是若干行命令,或者以分號(hào);結(jié)尾的放在同一行內(nèi)的多條命令。我們知道在傳統(tǒng)的shell中,分號(hào)本身并不是一條命令,空字符串也不是一條命令,因此,then后面緊接著的分號(hào)就會(huì)帶來一條語法錯(cuò)誤。(有些時(shí)候?qū)δ硞€(gè)“語言特性”的所謂解釋只是為了掩飾設(shè)計(jì)者在一開始犯的錯(cuò)誤,所以就此打住)
在Zsh中,上述兩種寫法都合法。因?yàn)樗试S只包含一個(gè)分號(hào)的空命令。
$ ;當(dāng)然,因?yàn)榉痔?hào)只是一個(gè)語句分隔符,所以沒有也是可以的。這種寫法在Zsh中合法:(then的語句塊為空)
if [ 1 ]; then fi第二彈
其實(shí)只是先挖個(gè)坑而已。我也不知道有沒有時(shí)間寫,暫且記上。
Zsh vs. Bash:不完全對(duì)比解析(2)
- 別名,函數(shù)定義和作用域
- 協(xié)進(jìn)程(coprocess)
- 重定向
- 信號(hào)和陷阱(trap)
?
?
Linux服務(wù)器上zsh和bash的對(duì)比
使用默認(rèn)指令列模式(bash shell)的管理員可能想仔細(xì)看看zshell或是zsh。由于它于bash相似,功能又有所加強(qiáng),zsh在Linux社區(qū)獲得了關(guān)注。那么zsh有什么不同之處呢?本文就列出在Linux服務(wù)器上zsh和bash的數(shù)據(jù)形式的對(duì)比。
作者:Mark 譯來源:TechTarget中國(guó)|2011-06-13 14:03?
使用默認(rèn)指令列模式(bash shell)的管理員可能想仔細(xì)看看zshell或是zsh。由于它于bash相似,功能又有所加強(qiáng),zsh在Linux社區(qū)獲得了關(guān)注。
那么zsh有什么不同之處呢?首先,zsh在感覺和功能上都和bash相似。但是一些增強(qiáng)功能讓zsh變成一個(gè)有趣的選擇。下面是一臺(tái)Linux服務(wù)器上zsh和bash的數(shù)據(jù)形式的對(duì)比:
Zsh增強(qiáng)功能:標(biāo)簽完成和拼寫錯(cuò)誤修正
用過bash標(biāo)簽完成的管理員會(huì)發(fā)現(xiàn)zsh中的增加功能令人印象深刻。這些功能包括菜單中現(xiàn)有的自動(dòng)完成命令選項(xiàng),該菜單可以通過使用箭頭鍵滾動(dòng)。舉例來說,鍵入以下命令將提供可能命令行標(biāo)記的列表:
$ ls -或是
$ rm -選擇要取消的特定程序,程序列表就和取消命令一起可用了。
另一個(gè)功能在內(nèi)置頁(yè)面程序中,它提供到less命令的快捷方式。要訪問它,輸入:
$<filename這和在命令行上運(yùn)行l(wèi)ess文件名一樣。
對(duì)笨拙的打字員來說,拼寫錯(cuò)誤修正功能可用了。例如,如果你輸入了一條錯(cuò)誤命令,zsh會(huì)提示修正:
$ llszsh: 要將 'lls'修改為 'ls' [nyae]嗎?
要修改它,輸入y,命令就更正為ls,接著命令就準(zhǔn)備運(yùn)行了。
其它選項(xiàng)也很實(shí)用。輸入n拒絕命令修正,輸入a中斷命令,輸入e跳轉(zhuǎn)到命令行進(jìn)行編輯。這個(gè)自動(dòng)修正功能也能用于命令行標(biāo)記和文件名,包括修改無效Git分支名稱一類的機(jī)密事務(wù)。
開始使用zsh
為了快速地開始使用zsh,可利用Robby Russell收集的zsh主題、功能和工具,它們被預(yù)先打包成“Oh My Zsh”。
$ wget --no-check-certificate https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh手動(dòng)的zsh安裝指令也可用,需要用戶克隆Git repo并復(fù)制在.zshrc的草稿模板中。
“Oh My Zsh”知識(shí)庫(kù)包含一個(gè)主題和功能集合用于現(xiàn)有zsh環(huán)境的建立和改變。它也能和卸載腳本一起用來簡(jiǎn)化移除:
$ uninstall_oh_my_zsh與zsh shell一起供給的還有一些很好的文檔和zsh參考卡。GitHub等網(wǎng)站上的在線資源是.zshrc文件的例子,它相當(dāng)于zsh版的.bashrc文件,這些資源同時(shí)也提供如何定制zsh的示例或是示范加強(qiáng)命令行經(jīng)驗(yàn)的炫酷技巧。
一些zsh功能可和bash一起用,但在bash上設(shè)置、配置更加復(fù)雜,這也解釋了為什么人們有多頁(yè).bashrc文件。如果是Shell的高度使用者,zsh會(huì)是吸引你用來取代bash的選擇。它的使用快速且簡(jiǎn)單,而它的一些重要功能也讓與shell的互動(dòng)更有趣。
原文:http://www.searchsv.com.cn/showcontent_49287.htm
總結(jié)
以上是生活随笔為你收集整理的Zsh vs. Bash不完全对比解析,zsh是一种更强大的被成为“终极”的Shell的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IDEA全局护眼色
- 下一篇: 单个APP接入多个微信支付宝支付的一种解