1.2. Bourne Again SHell 的优点

1.2.1. Bash 是 GNU shell

GNU 项目 (GNU's Not UNIX) 为类 UNIX 系统管理提供了工具,这些工具是自由软件,并符合 UNIX 标准。

Bash 是一个与 sh 兼容的 shell,它融合了 Korn shell (ksh) 和 C shell (csh) 的有用特性。 它旨在符合 IEEE POSIX P1003.2/ISO 9945.2 Shell 和工具标准。 它为编程和交互使用提供了优于 sh 的功能改进; 这些包括命令行编辑、无限大小的命令历史记录、作业控制、shell 函数和别名、无限大小的索引数组以及任何从 2 到 64 的进制的整数运算。 Bash 可以运行大多数 sh 脚本而无需修改。

与其他 GNU 项目一样,bash 倡议的启动是为了保护、维护和促进使用、研究、复制、修改和重新分发软件的自由。 众所周知,这些条件激发了创造力。 bash 程序也是如此,它具有许多其他 shell 无法提供的额外功能。

1.2.2. 仅在 bash 中发现的特性

1.2.2.1. 调用

除了通常可以使用 set shell 内置命令配置的单字符 shell 命令行选项之外,您还可以使用几个多字符选项。 我们将在本章和后续章节中遇到一些更流行的选项; 完整的列表可以在 Bash 信息页面中找到,Bash 功能->调用 Bash

1.2.2.2. Bash 启动文件

启动文件是 Bash 启动时读取和执行的脚本。 以下小节描述了启动 shell 的不同方式,以及随后读取的启动文件。

1.2.2.2.1. 作为交互式登录 shell 调用,或使用 `--login'

交互式意味着您可以输入命令。 shell 没有运行,因为脚本已被激活。 登录 shell 意味着您在向系统进行身份验证后获得了 shell,通常是通过提供您的用户名和密码。

读取的文件

  • /etc/profile

  • ~/.bash_profile, ~/.bash_login或者~/.profile: 首先读取现有的可读文件

  • ~/.bash_logout注销时。

如果配置文件存在但不可读,则会打印错误消息。 如果文件不存在,bash 会搜索下一个。

1.2.2.2.2. 作为交互式非登录 shell 调用

非登录 shell 意味着您不必对系统进行身份验证。 例如,当您使用图标或菜单项打开终端时,它是一个非登录 shell。

读取的文件

  • ~/.bashrc

通常在以下文件中引用此文件~/.bash_profile:

if[ -f~/.bashrc ]; then .~/.bashrc; fi

有关 if 构造的更多信息,请参见 第 7 章

1.2.2.2.3. 非交互式调用

所有脚本都使用非交互式 shell。 它们被编程为执行某些任务,并且不能被指示执行除为它们编程的任务之外的其他任务。

读取的文件

  • 由以下定义BASH_ENV

PATH不用于搜索此文件,因此如果您想使用它,最好通过给出完整路径和文件名来引用它。

1.2.2.2.4. 使用 sh 命令调用

Bash 尝试在符合 POSIX 标准的同时,表现得像历史悠久的 Bourne sh 程序一样。

读取的文件

  • /etc/profile

  • ~/.profile

当以交互方式调用时,ENV变量可以指向额外的启动信息。

1.2.2.2.5. POSIX 模式

可以使用 set 内置命令启用此选项

set-o posix

或者通过使用--posix选项调用 bash 程序。 然后,Bash 将尝试尽可能符合 shell 的 POSIX 标准。 设置POSIXLY_CORRECT变量的作用相同。

读取的文件

  • 由以下定义ENV变量。

1.2.2.2.6. 远程调用

rshd 调用时读取的文件

  • ~/.bashrc

Warning避免使用 r-tools
 

请注意使用 rlogintelnetrshrcp 等工具的危险。 它们本质上是不安全的,因为机密数据是通过网络以未加密的方式发送的。 如果您需要用于远程执行、文件传输等的工具,请使用安全 SHell 的实现,通常称为 SSH,可从 http://www.openssh.org 免费获得。不同的客户端程序也可用于非 UNIX 系统,请参阅您当地的软件镜像。

1.2.2.2.7. 当 UID 不等于 EUID 时调用

在这种情况下,不会读取任何启动文件。

1.2.2.3. 交互式 shell

1.2.2.3.1. 什么是交互式 shell?

交互式 shell 通常从用户的终端读取并写入到用户的终端:输入和输出连接到终端。 当调用 bash 命令时,如果不带任何非选项参数,则会启动 Bash 交互行为,除非该选项是要读取的字符串,或者调用 shell 从标准输入读取,这允许设置位置参数(请参阅 第 3 章)。

1.2.2.3.2. 此 shell 是否是交互式的?

通过查看特殊参数的内容进行测试-,当 shell 是交互式的时候,它包含一个 'i'

eddy:~> echo $-
himBH

在非交互式 shell 中,提示符,PS1未设置。

1.2.2.3.3. 交互式 shell 行为

交互模式下的差异

  • Bash 读取启动文件。

  • 默认情况下启用作业控制。

  • 提示符已设置,PS2已为多行命令启用,通常设置为 ">"。 这也是 shell 认为您输入了未完成的命令时获得的提示,例如,当您忘记引号、不能省略的命令结构等时。

  • 默认情况下,命令使用 readline 从命令行读取。

  • Bash 解释 shell 选项ignoreeof而不是在收到 EOF (文件结束) 时立即退出。

  • 默认情况下启用命令历史记录和历史记录扩展。 历史记录保存在由HISTFILE在 shell 退出时指向的文件中。 默认情况下,HISTFILE指向~/.bash_history.

  • 启用别名扩展。

  • 在没有陷阱的情况下,SIGTERM信号被忽略。

  • 在没有陷阱的情况下,SIGINT被捕获和处理。 因此,例如,键入 Ctrl+C 不会退出您的交互式 shell。

  • SIGHUP信号发送到退出时的所有作业是通过huponexit选项配置的。

  • 命令在读取时执行。

  • Bash 定期检查邮件。

  • 可以配置 Bash 以在遇到未引用的变量时退出。 在交互模式下,此行为被禁用。

  • 当 shell 内置命令遇到重定向错误时,这不会导致 shell 退出。

  • 在 POSIX 模式下使用时返回错误的特殊内置命令不会导致 shell 退出。 内置命令在 第 1.3.2 节 中列出。

  • exec 的失败不会导致 shell 退出。

  • 解析器语法错误不会导致 shell 退出。

  • 默认情况下启用对 cd 内置命令的参数的简单拼写检查。

  • TMOUT变量中指定的时间长度过去后,自动退出已启用。

更多信息

1.2.2.4. 条件

条件表达式由 [[ 复合命令和 test[ 内置命令使用。

表达式可以是单项的也可以是二元的。 单项表达式通常用于检查文件的状态。 您只需要一个对象,例如文件,即可对该对象执行操作。

也有字符串运算符和数字比较运算符; 这些是二元运算符,需要两个对象才能执行操作。 如果FILE其中一个主参数的参数的形式为/dev/fd/N,则检查文件描述符 N。 如果其中一个主参数的FILE参数之一是/dev/stdin, /dev/stdout或者/dev/stderr,则分别检查文件描述符 0、1 或 2。

第 7 章 详细讨论了条件。

有关 第 8.2.3 节 中文件描述符的更多信息。

1.2.2.5. Shell 算术

shell 允许评估算术表达式,作为 shell 扩展之一或通过 let 内置命令。

评估是在固定宽度的整数中完成的,没有溢出检查,但是被 0 除会被捕获并标记为错误。 运算符及其优先级和结合性与 C 语言相同,请参见 第 3 章

1.2.2.6. 别名

当一个字符串用作简单命令的第一个单词时,别名允许该字符串被替换为一个单词。 shell 维护一个别名列表,可以使用 aliasunalias 命令设置和取消设置这些别名。

Bash 始终在执行该行上的任何命令之前至少读取一行完整的输入。 当读取命令时(而不是执行命令时)扩展别名。 因此,与另一个命令出现在同一行上的别名定义直到读取下一行输入才会生效。 该行上别名定义之后的命令不受新别名的影响。

别名在读取函数定义时展开,而不是在函数执行时展开,因为函数定义本身就是一个复合命令。 因此,在函数中定义的别名在该函数执行后才可用。

我们将在第 3.5 节中详细讨论别名。

1.2.2.7. 数组

Bash 提供一维数组变量。 任何变量都可以用作数组;declare 内置命令将显式声明一个数组。 数组的大小没有最大限制,也没有要求成员被连续索引或分配。 数组是基于零的。 参见第 10 章

1.2.2.8. 目录栈

目录栈是最近访问过的目录的列表。 pushd 内置命令在更改当前目录时将目录添加到栈中,而 popd 内置命令从栈中删除指定的目录,并将当前目录更改为已删除的目录。

可以通过发出 dirs 命令或检查以下内容来显示内容:DIRSTACK变量。

有关此机制工作原理的更多信息,请参见 Bash info 页面。

1.2.2.9. 提示符

Bash 使玩转提示符更加有趣。 请参阅 Bash info 页面中的控制提示符部分。

1.2.2.10. 受限 Shell

当作为 rbash 调用或使用--restricted或者-r选项时,会发生以下情况:

  • cd 内置命令被禁用。

  • 设置或取消设置SHELL, PATH, ENV或者BASH_ENV是不可能的。

  • 命令名称不再包含斜杠。

  • 包含斜杠的文件名不允许与 . (source) 内置命令一起使用。

  • hash 内置命令不接受带以下参数的斜杠:-p选项配置的。

  • 启动时禁用函数导入。

  • SHELLOPTS在启动时被忽略。

  • 使用 >>|><>&&>>> 的输出重定向被禁用。

  • exec 内置命令被禁用。

  • 以下-f-d选项对 enable 内置命令禁用。

  • 无法使用 command 内置命令指定默认PATHcannot be specified with the command built-in.

  • 无法关闭受限模式。

当执行一个被发现是 shell 脚本的命令时,rbash 会关闭为执行该脚本而产生的 shell 中的任何限制。

更多信息