bash
bash 是一個為GNU計劃編寫的Unix shell缓熟。它的名字是一系列縮寫:Bourne-Again SHell — 這是關于Bourne shell(sh)的一個雙關語(Bourne again / born again)。Bourne shell是一個早期的重要shell摔笤,由史蒂夫·伯恩在1978年前后編寫够滑,并同Version 7 Unix一起發(fā)布。bash則在1987年由布萊恩·嘎朗溃克斯創(chuàng)造彰触。
bash (GNU Bourne-Again Shell) 是許多Linux發(fā)行版的默認Shell 。事實上命辖,還有許多傳統(tǒng)UNIX上用的Shell况毅,例如tcsh、csh尔艇、ash尔许、bsh、ksh等等漓帚,Shell Script大致都類同母债。
由于歷史原因午磁,UNIX系統(tǒng)上有很多種Shell:
csh(C Shell):由Bill Joy開發(fā)尝抖,隨BSD UNIX發(fā)布毡们,它的流程控制語句很像C語言,支持很多Bourne Shell所不支持的功能:作業(yè)控制昧辽,命令歷史衙熔,命令行編輯。
ksh(Korn Shell):由David Korn開發(fā)搅荞,向后兼容sh的功能红氯,并且添加了csh引入的新功能,是目前很多UNIX系統(tǒng)標準配置的Shell咕痛,在這些系統(tǒng)上
/bin/sh
往往是指向/bin/ksh
的符號鏈接痢甘。tcsh(TENEX C Shell):是csh的增強版本,引入了命令補全等功能茉贡,在FreeBSD塞栅、Mac OS X等系統(tǒng)上替代了csh。
bash(Bourne Again Shell):由GNU開發(fā)的Shell腔丧,主要目標是與POSIX標準保持一致放椰,同時兼顧對sh的兼容,bash從csh和ksh借鑒了很多功能愉粤,是各種Linux發(fā)行版標準配置的Shell砾医,在Linux系統(tǒng)上/bin/sh往往是指向/bin/bash的符號鏈接。
可使用cat /etc/shells
指令查看自己系統(tǒng)可以使用的shell種類:
用戶的默認 Shell 設置在/etc/passwd
文件中衣厘,例如:vim /etc/passwd
sh
在 shell 腳本的開頭往往有一句話來定義使用哪種 sh 解釋器來解釋腳本如蚜。
目前常見的 shell 腳本中主要有以下兩種方式:
(1) #!/bin/sh
(2) #!/bin/bash
注意:每個腳本開頭都使用"#!",#!實際上是一個2字節(jié)魔法數(shù)字头滔,這是指定一個文件類型的特殊標記怖亭,在這種情況下,指的就是一個可執(zhí)行的腳本坤检。在#!之后兴猩,接一個路徑名,這個路徑名指定了一個解釋腳本命令的程序早歇,這個程序可以是shell倾芝,程序語言或者任意一個通用程序。
sh是bash的一種特殊的模式箭跳,也就是 /bin/sh
相當于 /bin/bash --posix
晨另。說白了sh就是開啟了POSIX標準的bash 。
在一般的linux系統(tǒng)當中(如redhat)谱姓,使用sh調(diào)用執(zhí)行腳本相當于打開了bash的POSIX標準模式
sh一般設成bash的軟鏈:
怎么把sh改為指向bash呢借尿?
- 方法一:直接把/bin/sh的軟鏈接改到bash中,如:
ln -s /bin/bash /bin/sh
- 方法二:配置shell,
sudo dpkg-reconfigure dash
dash
鑒于 bash 過于復雜路翻,有人把 bash 從 NetBSD 移植到 Linux 并更名為 dash(Debian Almquist Shell)狈癞,并以獲得更快的腳本執(zhí)行速度。Debian Almquist shell茂契,縮寫為dash蝶桶,一種 Unix shell。它比 Bash 小掉冶,只需要較少的磁盤空間真竖,但是它的對話性功能也較少。它由 NetBSD版本的Almquist shell (ash)發(fā)展而來厌小,于1997年恢共,由赫伯特·許(Herbert Xu)移植到Linux上,于2002年改名為 dash璧亚。
ll -h /bin/
那么怎么把 sh 改為指 dash 呢旁振?
sudo dpkg-reconfigure dash
# 選擇yes使用dash作為默認的shell即可修改為dash。
#!/bin/bash
是指此腳本使用 /bin/bash 來解釋執(zhí)行涨岁。其中拐袜,#!
是一個特殊的表示符,其后梢薪,跟著解釋此腳本的shell路徑蹬铺。
bash 只是 shell 的一種,還有很多其它 shell秉撇,如:sh,csh,ksh,tcsh,…我們可以通過以下一個示例來進行實驗甜攀,了解#!/bin/bash的使用。
除第一行外琐馆,腳本中所有以“#”開頭的行都是注釋规阀。
1)#!/bin/bash只能放在第一行,如果后面還有#!瘦麸,那么只能看成是注釋谁撼。
這里有三個腳本(腳本都要使用”chmod +x scriptname“命令來獲得可執(zhí)行權(quán)限):
- tbash1.sh:
#!/bin/sh
source abc
echo “hello abc”
- tbash2.sh:
#!/bin/bash
source abc
echo “hello abc”
- tbash3.sh:
source abc
echo “hello abc”
三個腳本執(zhí)行的結(jié)果:
[nsvc@localhost other]$ ./tbash1.sh
./tbash1.sh: line 2: abc: No such file or directory
# 注:當source命令執(zhí)行有問題時,sh不再往下面執(zhí)行滋饲。
[nsvc@localhost other]$ ./tbash2.sh
./tbash2.sh: line 2: abc: No such file or directory
hello abc
# 注:當source命令執(zhí)行有問題時厉碟,bash繼續(xù)執(zhí)行下面命令。
[nsvc@localhost other]$ ./tbash3.sh
./tbash3.sh: line 1: abc: No such file or directory
hello abc
# 注:自身登錄系統(tǒng)所在的shell是bash屠缭。所以箍鼓,當source命令執(zhí)行有問題時,bash繼續(xù)執(zhí)行下面命令呵曹。
如果將 tbash1.sh 改成:
echo “abc”
#!/bin/sh
source abc
echo “hello abc”
那么款咖,執(zhí)行結(jié)果是:
[nsvc@localhost other]$ ./tbash1.sh
abc
./tbash1.sh: line 3: abc: No such file or directory
hello abc
# 也就是說何暮,腳本忽略了第二行“#!/bin/sh",直接使用當前所在的shell(也就是bash)來解釋腳本铐殃。
當把 tbash1.sh 改成:
#!/bin/sh
#!/bin/bash
source abc
echo “hello abc”
執(zhí)行結(jié)果為:
[nsvc@localhost other]$ ./tbash1.sh
./tbash1.sh: line 3: abc: No such file or directory
# 當執(zhí)行完source命令時郭卫,并沒有往下執(zhí)行。說明背稼,#!/bin/sh這一行起到作用了,但#!/bin/bash并沒有起作用玻蝌。在腳本中蟹肘,除第一行外,腳本中所有以“#”開頭的行都是注釋俯树。
2)#!后面的路徑一定要正確帘腹,不正確會報錯。
假如许饿,我們把tbash1.sh中第一行的#!后面加了一個不存在的路徑”/home/sh“:
#!/home/sh
source abc
echo “hello abc”
執(zhí)行結(jié)果為:
[nsvc@localhost other]$ ./tbash1.sh
-bash: ./tbash1.sh: /home/sh: bad interpreter: No such file ordirectory
# 系統(tǒng)會提示/home/sh的路徑不存在阳欲。
3)如果一個腳本在第一行沒有加上#!+shell路徑這一行,那么陋率,腳本會默認當前用戶登錄的shell球化,為腳本解釋器。
在1)中瓦糟,腳本 tbash3.sh 的執(zhí)行結(jié)果筒愚,就是用當前自己登錄的shell(bash)解釋后的結(jié)果。我們通常所用的shell都是bash菩浙,如果哪天登錄到sh巢掺,再使用以上類型的腳本,就會有問題劲蜻。以下是自己登錄到sh下陆淀,執(zhí)行tbash3.sh的結(jié)果:
-sh-3.2$ ./tbash3.sh
./tbash3.sh: line 1: abc: 沒有那個文件或目錄
與1)中的執(zhí)行結(jié)果是不一樣的。
因此先嬉,大家應該養(yǎng)成腳本首行加上#!+shell路徑的習慣轧苫。
4)/bin/sh
相當于 /bin/bash --posix
我們將腳本 tbash1.sh 改為:
#!/bin/bash --posix
source abc
echo “hello abc”
執(zhí)行結(jié)果:
[nsvc@localhost other]$ ./tbash1.sh
./tbash1.sh: line 2: abc: No such file or directory
# 與tbash1.sh原腳本執(zhí)行的結(jié)果一樣。
我們還可以以tbash3.sh為示例疫蔓。
用以下命令來執(zhí)行該腳本:
[nsvc@localhost other]$ bash tbash3.sh
tbash3.sh: line 1: abc: No such file or directory
hello abc
[nsvc@localhost other]$ sh tbash3.sh
tbash3.sh: line 1: abc: No such file or directory
[nsvc@localhost other]$ bash --posix tbash3.sh
tbash3.sh: line 1: abc: No such file or directory
"bash tbash3.sh"表示使用bash來作為腳本解釋器來執(zhí)行tbash3.sh浸剩。同樣,也可以使用如”sh腳本名“這樣的命令鳄袍,來用sh作為腳本解釋器绢要。
從結(jié)果可以看出,/bin/bash–posix
與/bin/sh
的執(zhí)行結(jié)果相同拗小≈刈铮總結(jié)起來,sh跟bash的區(qū)別,實際上是bash有沒開啟posix模式的區(qū)別剿配。遵守posix規(guī)范搅幅,可能包括,”當某行代碼出錯時呼胚,不繼續(xù)往下執(zhí)行茄唐。“
最后加上一點說明蝇更,每個腳本開頭都使用"#!"沪编,#!實際上是一個2字節(jié)魔法數(shù)字,這是指定一個文件類型的特殊標記年扩,在這種情況下蚁廓,指的就是一個可執(zhí)行的腳本。在#!之后厨幻,接一個路徑名相嵌,這個路徑名指定了一個解釋腳本命令的程序,這個程序可以是shell况脆,程序語言或者任意一個通用程序饭宾。