# Bash (简体中文)

From ArchWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

相关文章

- 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 (简体中文)#安装。

另一个"找不到命令"的钩子由 command-not-foundAUR 包提供，它看起来像这个样子：

    $ abiword

    The command 'abiword' is provided by the following packages:
    abiword (2.8.6-7) from extra
    	[ abiword ]
    abiword (2.8.6-7) from staging
    	[ abiword ]
    abiword (2.8.6-7) from testing
    	[ abiword ]

### 在终端内禁用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 (简体中文)