Bash (简体中文) - ArchWiki

Jump to content

相关文章

- Bash (简体中文)/Functions (简体中文)
- Bash (简体中文)/Prompt customization (简体中文)
- Environment variables (简体中文)
- Readline (简体中文)
- Fortune
- Pkgfile (简体中文)
- Command-line shell

翻译状态：本文是 Bash 的翻译。上次翻译日期：2021-06-24。如果英文版本有所更改，则您可以帮助同步翻译。

Bash (Bourne-again Shell) 是一个来自 GNU的命令行解释器/编程语言。它的名字是向它的前身——很早以前的 Bourne shell 致敬。Bash可以运行在大部分类 UNIX 操作系统中，包括 GNU/Linux。

Bash是Arch Linux的默认命令行解释器。

## 调用

Bash 的运行方式会取决于 Bash 被调用的方式。下面是一些不同模式的描述。

如果 Bash 以TTY中的`login`、SSH 守护进程、或者其它类似的方式派生出来，我们称之为登录 (login) shell。你可以使用命令行选项 `-l` 或 `--login` 来使用这种模式。

如果 Bash 的标准输入输出和标准错误输出都连接到终端(比如说，一个终端模拟器)，并且在启动的时候既没有使用 `-c` 选项和非选项参数(比如说，`bash script`)，我们称之为交互 (interactive) shell。所有的交互式 shell 都会执行`/etc/bash.bashrc` 和 `~/.bashrc` 文件中的配置，而登录shell还会执行`/etc/profile` 和 `~/.bash_profile` 中的配置。

注意： 在 Arch Linux 中 `/bin/sh` (过去是 Bourne shell 的执行文件名) 是 `/bin/bash` 的符号链接。如果 Bash 通过 `sh` 方式调用，它会尽量模拟历史上 `sh` 的启动行为，包括 POSIX 兼容能力。

通过在Bash启动时使用 `--posix` 命令行参数或者在启动后执行 ‘`set -o posix`’ 来使Bash在增强的POSIX标准下运行。

### 配置文件

Bash会在启动时按照不同的启动方式执行一系列启动文件。关于更详尽的描述，您可以参考GNU Bash 指南中`/usr/share/doc/bash/bashref.html` (Bash启动文件)这一节。

文件 | 描述 | 登录 shell (见下) | 交互 shell 非登录
--- | --- | --- | ---
`/etc/profile` | 加载全部储存在 `/etc/profile.d/*.sh` 和 `/etc/bash.bashrc` 中的配置。 | 是 | 否
`~/.bash_profile` | 针对每个用户，紧接 `/etc/profile` 执行。如果这个文件不存在，会顺序检查 `~/.bash_login` 和 `~/.profile` 文件。框架文件 `/etc/skel/.bash_profile` 同时会引用 `~/.bashrc`。 | 是 | 否
`~/.bash_logout` | 针对每个用户，退出登录 shell 后。 | 是 | 否
`/etc/bash.bash_logout` | 取决于 `-DSYS_BASH_LOGOUT="/etc/bash.bash_logout"` 编译标记。退出登录 shell 后。 | 是 | 否
`/etc/bash.bashrc` | 取决于编译标志 `-DSYS_BASHRC="/etc/bash.bashrc"`。加载 `/usr/share/bash-completion/bash_completion` 配置。 | 否 | 是
`~/.bashrc` | 针对每个用户，在 `/etc/bash.bashrc` 后加载。 | 否 | 是

注意：

- 如果以 `--login` 调用，登录 shell 可能不是交互式的。
- 如果可以交互，非登录 shell 不会 加载 `~/.bash_profile`。它会继承调用他们的父进程（可能是一个登录 shell）的环境参数。更多信息，请参考GregsWiki:ProcessManagement#On processes, environments and inheritance。

### Shell 与环境变量

Bash的行为和通过它启动的程序会被许多环境变量影响。环境变量用于储存有用的值，比如命令搜索路径，或者默认浏览器。当一个新的 shell 或者脚本被启动时，这个 shell 会继承它的父进程的环境变量，从而这个 shell 会带有内部 shell 变量[1]。

这些内部 shell 变量可以以此导出以变成环境变量：

    VARIABLE=content
    export VARIABLE

或者

    export VARIABLE=content

环境变量依照惯例放置在`~/.profile`或者`/etc/profile`中，这样其他兼容 Bourne shell 的 shell 也可以使用。

关于更详尽的内容，您可以参考Environment variables (简体中文)。

## 命令行

Bash 的命令行由一个叫做 Readline 的分离库来管理。Readline 提供了emacs 和 vi 风格的快捷键用于操作命令行，比如说，以单词为基准前后移动、删除等。管理输入历史也是 Readline 的职责。它还允许你创造宏。

### Tab 键补全

Tab 键补全，提供在按下 `tab` 键后自动补全命令的功能（这个功能默认启用）。

#### Tab 按下的次数

可能最多需要按三次 tab 才能显示所有的补全选项。如果希望减少这个数值，请参考 更快的补全操作。

#### 常用命令的选项补全

通常来讲，Bash 中按下 tab 只会补全命令、文件名和变量。安装 bash-completion 包，并加载 `/usr/share/bash-completion/bash_completion` 文件中的配置（这个文件应该已经在Arch的/etc/bash.bashrc中加载了），可以提供更多针对常见命令的选项的 tab 补全。安装这个包后，常规的补全（比如说 `$ ls file.*<tab><tab>`）可能会表现得不同。但是，您可以通过{ic|$ compopt -o bashdefault program}}命令来重新启用。(更多细节，请参考 [2] and [3]。)

#### 自定义命令补全

注意： 使用 `complete` 功能可能与 bash-completion 冲突。

通常来讲，Bash 中按下 tab 只会补全命令后的文件名。通过`complete -c`命令，Bash 可以规定某些命令后的补全形式为命令，比如：

    ~/.bashrc

    complete -c man which

或通过`-cf`命令，规定补全形式为命令和文件，比如：

    complete -cf sudo

更多补全形式，请参考Bash的手册页。

### 历史

#### 历史补全

您可以绑定上下键来在 Bash 的历史中查找（请参考 Readline (简体中文)#历史 and Readline 启动文件语法)：

    ~/.bashrc

     bind '"\e[A": history-search-backward'
     bind '"\e[B": history-search-forward'

或者所有 Readline 程序：

    ~/.inputrc

    "\e[A": history-search-backward
    "\e[B": history-search-forward

#### 更近的历史记录

`HISTCONTROL`变量可以避免历史记录记录特定的命令，比如不记录重复的命令

    ~/.bashrc

    export HISTCONTROL=ignoredups

将其设置为 `erasedups` 可以让 Bash 的历史记录对一条命令只保留一个历史记录（与顺序无关）。更多选项，请参考Bash的手册页。

#### 禁用历史记录

临时禁用历史记录：

    $ set +o history

现在输入的命令将不会存入`$HISTFILE`。

比如说，你现在可以执行 `printf secret | sha256sum` 来生成密码文件的散列值，或是隐藏您使用GPG的历史，如执行`gpg -eaF secret-pubkey.asc`命令。这些秘密不会被写入磁盘。

开启历史记录：

    $ set -o history

提示： 如果 `HISTCONTROL` 变量包含了 `ignorespace`，以空格开头的命令将不会记入历史。这样可以更加方便地控制历史记录。更多细节，请参考bash(1) § Shell Variables。

禁用所有的 Bash 历史：

    ~/.bashrc or /etc/profile

    export HISTSIZE=0

为了保险（这会永远清除所有的历史记录）：

    $ wipe -i -l2 -x4 -p4 "$HISTFILE"
    $ ln -sv /dev/null "$HISTFILE"

### 模仿 Zsh 的帮助功能

Zsh 可以在光标指向命令的时候按 `Alt+h` 来调用这个命令的手册。 相同的行为可以通过这个 Readline (简体中文) 绑定在 Bash 中开启：

    ~/.bashrc

    run-help() { help "$READLINE_LINE" 2>/dev/null || man "$READLINE_LINE"; }
    bind -m vi-insert -x '"\eh": run-help'
    bind -m emacs -x     '"\eh": run-help'

这个操作假设你使用（默认的）Emacs 编辑模式。

## 别名

别名（alias）是可以让您用另一个字符串来替换一个字符串的命令。这个命令常常被用来缩短系统命令，或者用来将默认参数加入到常用命令中。

推荐将针对用户的别名保存在`~/.bashrc`, 而将系统级的别名(这些会影响所有用户)存放在`/etc/bash.bashrc`。别名的示例，请参考 [4]。

关于函数，请参考 函数。

## 提示与技巧

### 自定义提示符

参见 自定义提示符。

### 找不到命令

pkgfile 提供了一个"找不到命令"的钩子，可以在输入未知命令后自动查找官方的软件包。

你需要加载这个钩子来启用它，如下：

    ~/.bashrc

    source /usr/share/doc/pkgfile/command-not-found.bash

现在，运行一个不可用的命令将会显示如下信息：

    $ abiword

    abiword may be found in the following packages:
      extra/abiword 3.0.1-2	/usr/bin/abiword

注意： 需要先更新 pkgfile 的数据库才能运作。更多细节，请参考pkgfile (简体中文)#安装。

### 在终端内禁用Ctrl+Z

你可以相这样包装你的命令，来关闭 `Ctrl+Z` 功能（暂停/关闭程序）。通过在这个脚本中包装命令

    #!/bin/bash
    trap "" 20
    adom

这时如果你在玩 adomAUR 要按 `Shift+Z` 组合键时不小心按下了 `Ctrl+Z` 组合键，你的游戏就不会停止运行了，因为我们已经禁用了`Ctrl+Z`。

### 登出后清空屏幕

当登出虚拟终端时，清空屏幕：

    ~/.bash_logout

    clear
    reset

### 输入路径自动添加"cd"

Bash 可以自动在输入的一个路径前添加 `cd` 。比如说：

    $ /etc

    bash: /etc: Is a directory

但是如果在 `.bashrc` 文件里添加一行:

    ~/.bashrc

    ...
    shopt -s autocd
    ...

你会得到：

    [user@host ~]$ /etc
    cd /etc
    [user@host etc]$

### 自动跳转

autojump-gitAUR 允许在用户访问最多的路径中搜索文件系统。

安装完后，加载 `/etc/profile.d/autojump.bash` 来启动这项功能。

### 防止覆盖文件

在当前的会话中，防止 shell 输出重定向覆盖一个已有的文件：

    $ set -o noclobber

这和`set -C`命令是一样的。

如果想让该用户一直生效：

    ~/.bashrc

    ...
    set -o noclobber

在设定 `noclobber` 的情况下强制覆盖文件：

    $ echo "output" >| file.txt

## 错误排除

### 修正窗口大小调整时的换行

如果您调整了终端模拟器的大小，Bash 可能并没有得到大小重调的信号，你键入的文本就不会正确的换行，并且与已输入内容重叠。启用 `checkwinsize` 选项可以在每一个命令后检查窗口的大小，并按需更新 `LINES` 和 `COLUMNS` 的值来调整。

    ~/.bashrc

    shopt -s checkwinsize

### 设置 ignoreeof 后 shell 仍然退出

如果您设置了 `ignoreeof` 选项，但是如果重复按下 `ctrl-D` shell 仍然会退出。因为这个选项只允许忽略 10 次连续的EOF记号（即 `Ctrl+D`）。

如果需要将这个次数调的更高，需要使用 IGNOREEOF 变量。

比如：

    export IGNOREEOF=100

### 分析代码以检查错误

包 shellcheck 可以分析bash脚本（以及其他脚本），显示可能存在的问题，并对优化代码质量提出意见。

shellcheck.net 网站也提供了基于此程序的相同功能。

## 更多信息 （英语）

- Wikipedia:Bash (Unix shell)
- Bash 参考手册，或是 `/usr/share/doc/bash/bashref.html`
- Readline 启动文件语法
- The Bourne-Again Shell - 开源软件架构 第三章
- PS1 生成器 - 生成你的 .bashrc/PS1 脚本，这样就可以在命令行中使用鼠标拖拽了。
- 有用的 .bashrc 命令

### 教程

- Greg's Wiki
- GregsWiki:BashGuide
- GregsWiki:BashFAQ
- Bash Hackers Wiki
- Bash Hackers Wiki: List of Bash online tutorials
- Quote Tutorial

### 社区

- 一个 Bash 的活跃友好的IRC频道

### 例子

- 怎样修改 xterm 的标题

Categories:

- Command-line shells (简体中文)
- GNU (简体中文)