Bash

来自 Arch Linux 中文维基

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

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

调用[编辑 | 编辑源代码]

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

如果 Bash 以TTY中的loginSSH 守护进程、或者其它类似的方式派生出来,我们称之为登录 (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 的执行文件名) 是 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 后加载。
注意:

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 提供了emacsvi 风格的快捷键用于操作命令行,比如说,以单词为基准前后移动、删除等。管理输入历史也是 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(1) § Programmable Completion

历史[编辑 | 编辑源代码]

历史补全[编辑 | 编辑源代码]

您可以绑定上下键来在 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

历史记录中重复命令(无论是否连续)只记录最后一条:

~/.bashrc
export HISTCONTROL=erasedups

不记录空格开头的命令:

~/.bashrc
export HISTCONTROL=ignorespace

不记录连续重复的命令、空格开头的命令:

~/.bashrc
export HISTCONTROL=ignoreboth

重复命令只记录最后一条,且不记录空格开头的命令:

~/.bashrc
export HISTCONTROL="erasedups:ignorespace"

更多选项,请参考手册bash(1) § HISTCONTROL

禁用历史记录[编辑 | 编辑源代码]

临时禁用历史记录:

$ set +o history

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

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

开启历史记录:

$ set -o history

禁用所有的 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, 或任意~/.bashrc加载的脚本。系统级的别名(这些会影响所有用户)存放在/etc/bash.bashrc。别名示例可参考 [4]

关于函数,请参考 函数

提示与技巧[编辑 | 编辑源代码]

自定义提示符[编辑 | 编辑源代码]

参见 自定义提示符

语法高亮与自动提示[编辑 | 编辑源代码]

blesh-gitAUR is a command line editor written in pure Bash which replaces Readline. It has many enhanced features like syntax highlighting, autosuggestions, menu-completion, abbreviations, Vim editing mode, hook functions, and more.

After installing it, source it in an interactive session. Configurations are explained in depth in the ~/.blerc file and at the wiki. The stable bleshAUR package is also available.

找不到命令[编辑 | 编辑源代码]

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]$

自动跳转[编辑 | 编辑源代码]

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

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

zoxideautojump的功能性能增强版,可直接替代。

防止覆盖文件[编辑 | 编辑源代码]

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

$ set -o noclobber

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

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

~/.bashrc
...
set -o noclobber

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

$ echo "output" >| file.txt

使用目录堆栈切换目录[编辑 | 编辑源代码]

pushdpopd以堆栈的方式控制目录切换,利于“撤销”目录切换动作。

 [user@host ~] pushd /tmp/dir1
 [user@host /tmp/dir1] pushd /var/lib
 [user@host/var/lib] popd
 [user@host/tmp/dir1] popd
 [user@host ~]

参见bash(1) § DIRSTACK

GNU readline alternative[编辑 | 编辑源代码]

ble.sh, packed as bleshAUR and blesh-gitAUR, is a full-featured line editor written in pure Bash. It is an alternative to GNU readline. It offers syntax highlighting, enhanced completion, vim editing mode, and other interesting features include status line, history share, right prompt, transient prompt, xterm title, etc.

错误排除[编辑 | 编辑源代码]

修正窗口大小调整时的换行[编辑 | 编辑源代码]

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

~/.bashrc
shopt -s checkwinsize

设置 ignoreeof 后 shell 仍然退出[编辑 | 编辑源代码]

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

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

比如:

export IGNOREEOF=100

分析代码以检查错误[编辑 | 编辑源代码]

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

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

更多信息 (英语)[编辑 | 编辑源代码]

教程[编辑 | 编辑源代码]

社区[编辑 | 编辑源代码]

例子[编辑 | 编辑源代码]