Linux 中 sh 和 bash 有什麼區別?
- 寫在前面
本文主要介紹:什麼是 shell、當前系統默認 shell / 可用 shell 列表,以及 sh 與 bash 之間的區別。
- 什麼是 shell?
在計算機科學中,shell 俗稱殼(用來區別於核),是指 “爲使用者提供操作界面” 的軟件(command interpreter,命令解析器)。它類似於 DOS 下的 COMMAND.COM 和後來的 cmd.exe 。它接收用戶命令,然後調用相應的應用程序。
bash shell 是 Linux 中的默認 shell,通常也是所有用戶首先熟悉的 shell。除此之外,也可以使用許多其他 shell 工具,例如 sh、zsh、ksh、csh 和 tcsh 等。
通過示例理解 shell 執行流程,如,打開系統終端並運行以下命令:
root@jpzhang:~# date
-------------------------------------------------------------------------------------
2024年 04月 07日 星期日 11:52:04 CST
執行流程:
-
默認 shell 接受命令 “date”,解釋並運行 date 工具;
-
在控制檯屏幕上打印輸出結果;
各種 Unix shell:
第一個 Unix shell 是由肯 · 湯普遜,仿效 Multics 上的 shell 所實現出來,稱爲 sh。
Bourne shell 兼容
-
Bourne shell(sh)史蒂夫 · 伯恩在貝爾實驗室時編寫。1978 年隨 Version 7 Unix 首次發佈。
-
Almquist shell(ash)
-
Bourne-Again shell(bash)
-
Debian Almquist shell(dash)
-
Korn shell(ksh)David Korn 在貝爾實驗室時編寫
-
Z shell(zsh)
C shell 兼容
-
C shell(csh)比爾 · 喬伊在加州大學伯克利分校時編寫。1979 年隨 BSD 首次發佈。
-
TENEX C shell(tcsh)
其他
-
fish,第一次發佈於 2005 年。
-
rc shell(rc)九號項目系統的 shell,由 Tom Duff 在貝爾實驗室時編寫。隨後移植回 Unix 和其他的操作系統。
-
es shell(es)一個函數式編程的 rc 兼容 shell,編寫於二十世紀九十年代中期。
-
scsh(Scheme shell)
2.1 如何查看當前使用的 shell?
可以通過以下命令,查看當前使用的 shell:
root@jpzhang:~# grep $USER /etc/passwd
-------------------------------------------------------------------------------------
root:x:0:0:root:/root:/bin/bash
-
$USER:當前登錄的用戶;
-
/etc/passwd:存儲用戶賬戶信息;
或者:
# 缺點:不能實時反映當前 shell
root@jpzhang:~# echo $shell
-------------------------------------------------------------------------------------
/bin/bash
可以看到默認使用的 shell 是 bash。因此,當我們使用終端時,命令將由 bash 解釋執行。
2.2 如何查看當前發行版可以使用的 shell ?
通過讀取 /etc/shell
文件,可以列出當前 Linux 發行版上有哪些可用的 shell:
root@jpzhang:~# cat /etc/shells
-------------------------------------------------------------------------------------
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/bin/rbash
/bin/dash
/usr/bin/tmux
/usr/bin/screen
- 什麼是 sh ?
sh 又稱 Bourne shell,是一種用於類 UNIX 系統的命令編程語言,由 POSIX(Portable Operating System Interface)標準定義,在大多數 Linux 系統中,它是由原始的 Bourne shell、dash 和 ksh 等程序實現的。
POSIX(Portable Operating System Interface,可移植操作系統接口)是由 IEEE(Institute of Electrical and Electronics Engineers)定義的一組操作系統接口標準。它的目標是爲應用程序提供一套與操作系統無關的接口,使得這些應用程序能夠在不同的 POSIX 兼容系統上編譯和運行。因此,它可以幫助我們通過遵循一系列準則,爲多個操作系統開發跨平臺軟件。
大多數系統都有 /bin/sh 文件,但它是一個符號鏈接指向 Bourne shell。在 Ubuntu 中,/bin/sh 是指向到 dash shell 的符號鏈接。我們可以通過運行下面的命令來檢查:
root@jpzhang:~# file -h /bin/sh
-------------------------------------------------------------------------------------
/bin/sh: symbolic link to dash
正如所看到的,/bin/sh
是到 dash 的符號鏈接,後者是 Debian 發行版使用的 POSIX 兼容 shell。在 shell 腳本中,可以將 #!/bin/sh
作爲第一行,然後由 dash 執行:
#!/bin/sh
echo Hello, World!
上面的腳本指定 /bin/sh 作爲解釋器。然而,由於 /bin/sh 指向 dash,dash shell 將作爲解釋器執行腳本。因此,該腳本可以移植到其他兼容 POSIX 的操作系統上,因爲它遵循了 POSIX 標準。
【注意】
大多數 shell 腳本的第一行都是 #!/bin/sh,但需要注意的是,/bin/sh 可能不是指向 Bourne 兼容 shell 的符號鏈接。有時,腳本作者會假定 /bin/sh 指向 /bin/bash 或 /bin/dash,但實際上有可能並不是這樣。因此,在編寫和執行腳本之前,最好先檢查 /bin/sh 的類型。
- 什麼是 bash?
與 sh 一樣,bash(Bourne Again shell)也是一種命令語言處理器和 shell。它是大多數 Linux 發行版默認登錄 shell。bash 是 sh 的超集,這意味着 bash 支持 sh 的功能,並在此基礎上提供了更多擴展和特性。不過,大多數命令的工作方式與 sh 類似。
自 bash 發佈以來,它已成爲 Linux 操作系統 shell。但是,bash 不是符合 POSIX 標準的 shell,而是 POSIX shell 語言的方言。bash 旨在成爲 IEEE POSIX 規範(IEEE 標準 1003.1)的 IEEE POSIX shell 和工具部分的一致實現。
4.1 如何使 bash 符合 POSIX 標準?
可以在 POSIX 兼容模式下使用 bash,通過設置 -posix
參數在 POSIX 模式下使用,如下所示:
$ bash --posix
另外,我們也可以讓 bash 腳本符合 POSIX 標準:
#!/bin/bash
set -o posix
echo Hello, World
set
命令可在腳本中啓用選項,在本例中將以 POSIX 模式運行腳本。因此,它使腳本可移植到其他操作系統,如 FreeBSD 和類 UNIX 系統。
4.2 bash 特性
bash 提供了很大的靈活性和語法,使其語法很像流行的編程語言。
特性:
-
使用 鍵,可以快速完成命令補全操作;
-
命令歷史記錄,可以通過使用 <向上> 方向鍵或 快速搜索以前執行過的命令;
-
算術運算,無需任何第三方工具;
-
關聯數組,能夠創建具有字符串索引的數組;
-
鍵盤快捷鍵,用於命令行編輯;
-
自定義功能,可以修改 bash 提供的默認顯示方式;
4.3 編寫 bash 腳本
指定 #!/bin/bash
作爲第一行,如下:
#!/bin/bash
# Determine if the number is odd or even
read -p "Enter a number: " number
if [ `expr $number % 2` -eq 0 ]; then
echo "${number} is even"
else
echo "${number} is odd"
fi
保存腳本文件並使其可執行:
root@jpzhang:~/linux# chmod +x bash_test.sh
root@jpzhang:~/linux# ./bash_test.sh
-------------------------------------------------------------------------------------
Enter a number: 12
12 is even
該腳本可在大多數 Linux 發行版上運行,但如果在 FreeBSD 上運行相同的腳本,可能會遇到問題。
- sh 與 bash 的區別
從歷史背景來看,sh 和 bash 的相似之處多於差異,主要區別在於:
-
默認 shell
當前大多數現代系統中,bash 是默認 shell;/bin/sh 往往是指向具體實現的符號鏈接;
-
二進制文件
root@jpzhang:~/linux# which sh ------------------------------------------------------------------------------------- /bin/sh root@jpzhang:~/linux# which bash ------------------------------------------------------------------------------------- /bin/bash
-
特性
與 sh 相比,bash 提供了更大的靈活性和語法,看起來像現代編程語言;
如上所述特性:
使用 <TAB> 鍵,可以快速完成命令補全操作; 命令歷史記錄,可以通過使用<向上>方向鍵或 <CTRL-R> 快速搜索以前執行過的命令; 算術運算, 無需任何第三方工具; 關聯數組,能夠創建具有字符串索引的數組; 鍵盤快捷鍵, 用於命令行編輯; 自定義功能,可以修改 bash 提供的默認顯示方式;
-
POSIX 合規性
默認情況下,bash 不符合 POSIX 標準,可以使用命令在 POSIX 兼容模式下運行 bash;sh 遵循 POSIX 規範,提供了更好的可移植性;
-
執行面
sh:當某行代碼出錯時,不繼續往下執行;bash:就算出錯,也會繼續向下執行;
sh 測試腳本:
#!/bin/sh source .env echo "Error message"
bash 測試腳本:
#!/bin/bash source .env echo "Error message"
執行如下:
root@jpzhang:~/linux/bash_sh# sh sh_test.sh sh_test.sh: 3: sh_test.sh: source: not found Error message ------------------------------------------------------------------------------------- root@jpzhang:~/linux/bash_sh# sh bash_test sh: 0: Can't open bash_test
可以看到,sh 報錯依舊可以輸出消息;
- 使用哪一種?
這兩個 shell 都很有用,我們可以在不同的情況下使用它們,具體取決於項目的需求。如果創建的腳本需要在多種 Unix 系統上運行,那麼 sh 可能是更好的選擇,因爲它具有可移植性和兼容性。如果你在 Linux 或 macOS 系統上進行工作,需要額外的功能和語法增強,bash 則是首選 shell。當然,如果我們對可移植性和兼容性有偏執,可以使用 bash 並在純 POSIX 模式下運行它。
除此之外,如果我們編寫一個 sh 腳本,它很可能無需修改即可在 bash 上運行,因爲 bash 向後兼容 sh。
- 結論
sh 是 bash 的前身,它們都可以在所有現代 UNIX/Linux 系統上使用。bash 提供了更舒適且易於使用的體驗,而 sh 提供了兼容性、可移植性和標準化語法 / 行爲。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/ErWUwKTWRQQG8S6rznmhLg