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 标准。它为编程和交互式使用提供了对 sh 的功能改进;其中包括命令行编辑、无限大小的命令历史、作业控制、shell 函数和别名、无限大小的索引数组以及从 2 到 64 的任何基数的整数运算。Bash 无需修改即可运行大多数 sh 脚本。

bash 程序具有许多其他 shell 无法提供的额外功能。

1.2.2. bash独有特性

1.2.2.1. 选项

除了通常可以使用set shell 内置命令配置的单字符命令行选项之外,您还可以使用多字符选项。

1.2.2.2. Bash启动文件

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

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

交互式意味着您可以输入命令。登录 shell 意味着您在对系统进行身份验证后获得了 shell,通常是提供您的用户名和密码。

文件读取:

  • /etc/profile
  • ~/.bash_profile, ~/.bash_login or ~/.profile: 读取第一个现有的可读文件
  • ~/.bash_logout upon logout.

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

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

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

文件读取:

  • ~/.bashrc

该文件通常在~/.bash_profile 中引用:

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

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启用此选项:

设置-o posix

或者通过使用—posix选项调用bash程序。然后,Bash 将尝试尽可能地符合 shell 的 POSIX 标准。设置POSIXLY_CORRECT变量也是如此。

文件读取:

  • 由ENV变量定义。

1.2.2.2.6. 远程调用

rshd调用时读取的文件:

  • ~/.bashrc

    1.2 bash的高级特性 - 图1
    避免使用 r-tools

请注意使用rlogintelnetrshrcp等工具时的危险。它们本质上是不安全的,因为机密数据是通过未加密的网络发送的。如果您需要远程执行、文件传输等工具,请使用 Secure SHell 的实现,通常称为 SSH。

1.2.2.2.7. 当 UID 不等于 EUID 时调用

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

1.2.2.3. 交互式 shells

1.2.2.3.1. 什么是交互式 shell?

交互式shell通常从用户终端读取和写入:输入和输出连接到终端。bash 交互在没有非选项参数的情况下调用bash命令时启动,除非选项是要读取的字符串或调用 shell 以从标准输入读取,这允许设置位置参数(参见第 3 章)。

1.2.2.3.2. 这个shell是交互式的么?

通过查看特殊参数标记’-‘进行测试,当 shell 为交互式,它包含一个 ‘i’:

  1. eddy:~> echo $-
  2. himBH

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

1.2.2.3.3. 交互式shell行为

区别:

  • Bash 读取启动文件。
  • 默认情况下启用作业控制。job control
  • 设置了提示, PS2启用多行命令, 通常为”>”. 这也是当 shell 认为你输入了一个未完成的命令时得到的提示,例如当你忘记引号、不能省略的命令结构等时。

    1. bash-5.1$ clear \
    2. > sadsad\
    3. >
  • 默认情况下,使用readline从命令行读取命令。

  • Bash 解释 shell 选项ignoreeof而不是在收到 EOF(文件结束)时立即退出。
  • 命令历史和历史扩展默认启用。当 shell 退出时,历史记录保存在HISTFILE指向的文件中。默认情况下,HISTFILE指向~/.bash_history。
  • Alias 扩展已启用.
  • 如果没有trap信号,则忽略SIGTERM
  • 如果没有trap信号,会捕获并处理SIGINT。因此,例如,键入Ctrl + C不会退出您的交互式 shell
  • 使用huponexit选项配置退出时,向所有job发送SIGHUP信号。
  • 命令在读取时执行。
  • Bash 会定期检查邮件。
  • Bash 可以配置为在遇到未引用的变量时自动退出。在交互模式下,此行为被禁用。
  • 当 shell 内置命令遇到重定向错误时,这不会导致 shell 退出。
  • 在 POSIX 模式下使用时返回错误的特殊内置函数不会导致 shell 退出。内置命令在1.3.2 节中列出。
  • exec的失败并不会退出 shell。
  • 解析器语法错误不会导致 shell 退出。
  • 默认情况下启用对cd参数的简单拼写检查。
  • 已启用在TMOUT变量后,会自动退出。

更多信息:

1.2.2.4. 条件

条件表达式使用 [[ 复合命令,测试可以用内置命令[.

表达式可以是一元或二元的。一元表达式通常用于检查文件的状态。您只需要一个对象(例如文件)来执行操作。

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

Chapter 7.详细讨论了条件。

Section 8.2.3有文件描述符的更多信息。

1.2.2.5. Shell算术

shell 允许计算算术表达式,也是 shell 扩展之一,或通过let内置。

计算是在固定宽度的整数中完成的,不检查溢出,尽管除以 0 会被捕获并标记为错误。运算符及其优先级和关联性与 C 语言中的相同,请参见第 3 章

1.2.2.6. Aliases

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

Bash 总是在执行任何命令之前读取至少一个完整的输入行。别名在读取命令时扩展,而不是在执行命令时扩展。

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

1.2.2.7. 数组

Bash 提供一维数组变量。任何变量都可以作为数组;内置的declare将显式声明一个数组。数组的大小没有最大限制,也没有要求连续索引或分配成员。数组是从零开始的。

1.2.2.8. 目录stack

录堆栈是最近访问过的目录的列表。PUSHD增加目录堆栈。POPD从堆栈中删除指定的目录。

可以通过dirs命令或检查DIRSTACK变量的内容来显示内容。

1.2.2.9. 提示

Bash 让提示变得更加有趣。

1.2.2.10. 严格受限 shell

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

  • CD是禁用的
  • 设置或取消设置SHELL、PATH、ENV或BASH_ENV是不能的。
  • 命令名称不能再包含斜杠。
  • 包含斜杠的文件名不允许。
  • hash不接受-p选项
  • 启动时导入函数被禁用。
  • SHELLOPTS在启动时被忽略。
  • 输出重定向使用> , >| , >< , >& , &>>>被禁用。
  • EXEC被禁用。
  • enable的-f和-d选项被禁用。
  • 不能使用命令指定默认PATH。
  • 无法关闭受限模式。