Contents

SH和Bash有什么区别?

1. 概述

在本教程中,我们将讨论sh和 Bash之间的区别,以及它们提供的功能。最后,我们将讨论使用哪个 shell。

2. 什么是shell?

shell 是一种计算机程序,它接受命令、解释它们并将它们传递给操作系统进行处理。因此,它是用户和操作系统之间的接口,用户可以通过它与计算机进行交互。要与 shell 交互,我们需要一个终端模拟器,例如gnome-terminalkonsole 或*st *。

大多数基于 Linux 的操作系统都带有至少一个 shell 程序。shell 程序可能是DashBash 或两者兼而有之。

2.1. 当前shell

我们可以通过简单地使用grep 读取*/etc/passwd*文件来找出我们当前使用的 shell :

$ grep $USER /etc/passwd
hey:x:1000:998::/home/hey:/bin/bash
  • grep命令需要一个模式和一个文件来读取
  • $USER环境变量扩展为当前登录的用户
  • / etc/passwd文件存储用户帐户信息

通过发出命令,我们可以看到使用的默认 shell 是bash。因此,当我们使用终端模拟器时,我们的命令将由bash解释。

2.2. 已安装的shell

我们可以通过读取*/etc/shell*文件列出当前安装在我们机器上的所有shell:

$ cat /etc/shells
# Pathnames of valid login shells.
# See shells(5) for details.
/bin/sh
/bin/bash
/bin/dash

我们可以看到我们的机器上安装了三个 shell。从技术上讲,我们有两个 shell,我们将在下一节中了解原因。

3. sh

sh也称为 Bourne Shell,是一种用于类 UNIX 系统的命令编程语言,由 POSIX 标准定义sh可以从键盘或文件(通常称为脚本文件)获取输入。在大多数 Linux 系统上,它是由原始的Bourne Shelldash和 ksh 等程序实现的。

3.1. sh在 POSIX 系统上

POSIX 是 IEEE 定义的一系列标准,供供应商使操作系统兼容。因此,它可以帮助我们按照一套指导方针为多个操作系统开发跨平台软件。sh符合这些标准。

在大多数 Linux 系统上,sh是 Bourne Shell 实际实现的符号链接。我们可以通过以下命令进行验证:

$ 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 线指向,在我们的例子中是dash。因此,我们的脚本可以移植到其他兼容 POSIX 的操作系统,因为它符合 POSIX 标准。

3.2. 常见的陷阱

大多数 shell 脚本都有*#!/bin/sh作为第一行,但我们应该注意/bin/sh可能不是与 Bourne 兼容的 shell 的符号链接。有时,脚本编写者假设/bin/sh指向/bin/bash/bin/dash*,这并不需要。

因此,最好在编写和执行脚本之前检查*/bin/sh*的类型。

4. bash

sh一样,Bash (Bourne Again Shell) 是一个命令语言处理器和一个 shell。它是大多数 Linux 发行版上的默认登录 shell。Bash 是sh 的超集,这意味着 Bash 支持sh的功能并在此基础上提供更多扩展。不过,大多数命令的工作方式与sh中的类似。

自 Bash 发布以来,它一直是 Linux 操作系统事实上的 shell。

4.1. Bash 作为 POSIX 兼容的 Shell

很长一段时间,/bin/sh都与*/bin/bash* 挂钩。随着时间的推移,bash开发了更多的特性和扩展,其中一些不符合 POSIX 标准。因此,在大多数 Linux 发行版上它不再是一个选项,而其他符合 POSIX 的 shell 取代了它。

尽管如此,我们仍然可以在 POSIX 兼容模式下使用 Bash,我们可以使用bash命令的*–posix*标志调用它:

$ bash --posix

或者,我们可以有一个符合 POSIX 标准的 Bash 脚本:

#!/bin/bash
set -o posix
echo Hello, World

set命令启用脚本中的选项,set这种情况下,它将以 POSIX 模式运行脚本。因此,它使脚本可移植到其他操作系统,例如 FreeBSD 和类 UNIX 系统。

4.2. 特征

Bash 提供了很多灵活性和语法,看起来很像现代编程语言。Bash 中引入的一些显着特性是:

  • 命令行补全可用于使用TAB键快速补全命令
  • 命令历史记录,我们可以通过它快速搜索以前使用Up箭头键或CTRL-R执行的命令
  • 无需使用外部程序即可进行算术评估
  • 关联数组,它使我们能够创建带有字符串索引的数组
  • 用于命令行编辑的键盘快捷键
  • 可定制性使我们能够修改 Bash 提供的默认演示文稿

4.3. 编写 Bash 脚本

Bash 还能够从文件中读取命令。我们将*#!/bin/bash* Shebang 指定为第一行,然后是我们的脚本:

#!/bin/bash
# Finds out whether a number is even or odd
read -p "Enter a number: " number
if [ `expr $number % 2` -eq 0 ]; then
    echo "${number} is even"
else
    echo "${number} is odd"
fi

保存脚本文件并使其可执行:

$ chmod +x is_even.sh
$ ./is_even
Enter a number: 13
13 is odd

该脚本将在大多数 Linux 发行版上运行,但如果我们在 FreeBSD 上运行相同的脚本,我们可能会遇到问题。

5. 使用哪一个?

这两个 shell 都很有用,我们可以在不同的情况下利用它们。例如,如果我们希望我们的脚本在多个系统之间兼容,我们可以使用*sh 。*另一方面,我们可能会选择 Bash,因为它提供了流畅的语法和更引人注目的功能。

尽管如此,如果我们对可移植性和兼容性有偏执,我们可以使用 Bash 并在纯 POSIX 模式下运行它。除此之外,如果我们编写一个sh脚本,它很可能无需修改就可以在 Bash 上运行,因为 Bash 与sh向后兼容。