Bash
Bash (Bourne-Again SHell) 是 命令行 Shell/编程语言,由 GNU Project 开发。它的名字暗指其前身,已长期弃用的 Bourne shell。Bash 可以在大多数 类 Unix 操作系统上运行,包括 GNU/Linux。
Bash 是 Arch Linux 上的默认命令行 Shell。
调用
Bash 的行为可以根据其调用方式进行更改。下面是一些不同模式的描述。
如果 Bash 是由 login 在 TTY 中启动,或者由 SSH 守护进程或类似方式启动,它就被认为是 **login shell**。此模式也可以通过 -l/--login 命令行选项启用。
当 Bash 的标准输入、输出和错误连接到终端(例如,在终端模拟器中运行时),并且没有使用 -c 选项或 非选项参数(例如,bash script)启动时,它就被认为是 **interactive shell**。所有交互式 Shell 都会 source /etc/bash.bashrc 和 ~/.bashrc,而交互式 *login* shell 还会 source /etc/profile 和 ~/.bash_profile。
/bin/sh(以前是 Bourne shell 可执行文件)被符号链接到 bash。如果 Bash 以 sh 名称调用,它会尝试模仿旧版 sh 的启动行为,包括 POSIX 兼容性。配置文件
Bash 会尝试根据其调用方式执行一组启动文件。有关完整描述,请参阅 GNU Bash 手册的 Bash Startup Files 部分。
| 文件 | 描述 | Login shells (见注释) | 交互式,*非login* shells |
|---|---|---|---|
/etc/profile
|
/etc/profile.d/*.sh 和 /etc/bash.bashrc 中的应用程序设置。 |
是 | 否 |
~/.bash_profile
|
用户级别,在 /etc/profile 之后。如果此文件不存在,则按顺序检查 ~/.bash_login 和 ~/.profile。骨架文件 /etc/skel/.bash_profile 也会 source ~/.bashrc。 |
是 | 否 |
~/.bash_logout
|
用户级别,在 login shell 退出后。 | 是 | 否 |
/etc/bash.bash_logout
|
取决于 -DSYS_BASH_LOGOUT="/etc/bash.bash_logout" 编译标志。在 login shell 退出后。 |
是 | 否 |
/etc/bash.bashrc
|
取决于 -DSYS_BASHRC="/etc/bash.bashrc" 编译标志。Source /usr/share/bash-completion/bash_completion。 |
否 | 是 |
~/.bashrc
|
用户级别,在 /etc/bash.bashrc 之后。 |
否 | 是 |
- Login shells 可以是非交互式的,当使用
--login参数调用时。 - 虽然交互式、*非login* shells 不会 source
~/.bash_profile,但它们仍然继承其父进程的环境(可能是 login shell)。有关详细信息,请参阅 GregsWiki:ProcessManagement#On processes, environments and inheritance。
Shell 和环境变量
Bash 的行为以及由它运行的程序可以受到许多环境变量的影响。 环境变量用于存储有用的值,例如命令搜索目录或要使用的浏览器。当启动新的 Shell 或脚本时,它会继承其父变量,从而以一组内部 Shell 变量开始[1]。
这些 Bash 中的 Shell 变量可以被导出,以成为环境变量
VARIABLE=content export VARIABLE
或使用快捷方式
export VARIABLE=content
环境变量通常放在 ~/.profile 或 /etc/profile 中,以便其他 Bourne 兼容的 Shell 可以使用它们。
有关更一般的信息,请参阅 环境变量。
命令行
Bash 命令行由名为 Readline 的独立库管理。Readline 提供 emacs 和 vi 风格的快捷方式来与命令行交互,例如按单词为单位前后移动、删除单词等。管理输入命令的 历史记录也是 Readline 的职责。最后但同样重要的是,它允许您创建 宏。
Tab 自动补全
Tab 自动补全是通过按 Tab 键自动完成输入的命令的选项(默认启用)。
单次 Tab
可能需要按三次 Tab 键才能显示命令的所有可能补全。要减少所需的 Tab 键次数,请参阅 Readline#Faster completion。
常用程序和选项
默认情况下,Bash 只会自动补全命令、文件名和变量。 bash-completion 包通过添加对常用命令及其选项更专业的 Tab 自动补全来扩展此功能,可以通过 source /usr/share/bash-completion/bash_completion 来启用(这在 Arch 的 /etc/bash.bashrc 中已经 source)。使用 bash-completion 后,普通补全(例如 ls file.* Tab Tab)的行为会不同;但是,可以使用 compopt -o bashdefault program 重新启用它们(有关更多详细信息,请参阅 [2] 和 [3])。
自定义每条命令
complete 内建命令可能会与 bash-completion 产生冲突。默认情况下,Bash 只会自动补全命令后面的文件名。您可以使用 complete -c 将其更改为补全命令名
~/.bashrc
complete -c man which
或使用 -cf 补全命令名和文件名
complete -cf sudo
有关更多补全选项,请参阅 bash(1) § Programmable Completion。
历史
历史记录补全
您可以将上箭头和下箭头键绑定到 Bash 历史记录的搜索(参见:Readline#History 和 Readline Init File Syntax)
~/.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。
禁用历史记录
仅临时禁用 bash 历史记录
$ set +o history
现在输入的命令不会被记录到 $HISTFILE。
例如,现在您可以使用 printf secret | sha256sum 对密码进行哈希处理,或者隐藏 GPG 用法,例如 gpg -eaF secret-pubkey.asc,这样您的秘密就不会写入磁盘。
启用历史记录
$ set -o history
禁用所有 bash 历史记录
~/.bashrc or /etc/profile
export HISTSIZE=0
……只是为了确保,永远删除您的旧 histfile
$ wipe -i -l2 -x4 -p4 "$HISTFILE" $ ln -sv /dev/null "$HISTFILE"
模仿 Zsh 的 run-help 功能
Zsh 按 Alt+h 可以调用光标前命令的手册。在 Bash 中使用此 Readline 绑定可以获得类似的行为
~/.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 编辑模式。
跨机器共享 bash 历史记录
atuin 使用 SQLite 数据库替换您现有的 Shell 历史记录,并记录命令的额外上下文。此外,它还通过 Atuin 服务器提供跨机器历史记录的可选且完全加密的同步。
在同步之前启用 bash 历史记录时间戳(export HISTTIMEFORMAT="%F %T ")。 Atuin 与 blesh-gitAUR 和 cmd-wrapped 等工具配合使用,可在跨机器时提供增强的终端体验。
别名 (Aliases)
别名(alias)是一个命令,它允许将一个词替换为另一个字符串。它通常用于缩写系统命令,或为经常使用的命令添加默认参数。
个人别名可以存储在 ~/.bashrc 或从 ~/.bashrc source 的任何单独文件中。系统范围的别名(影响所有用户)应放在 /etc/bash.bashrc 中。有关示例别名,请参阅 [4]。
有关函数,请参阅 Bash/Functions。
技巧与提示
提示符自定义
请参阅 Bash/Prompt customization。
语法高亮和自动建议
ble.sh (Bash Line Editor),打包为 blesh-gitAUR,是一个用纯 Bash 编写的命令行编辑器,是 GNU Readline 的替代品。它具有许多增强功能,如语法高亮、自动建议、菜单补全、缩写、Vim 编辑模式和钩子函数。其他有趣的功能包括状态行、历史记录共享、右提示符、瞬时提示符和 xterm 标题。
安装后,在交互式会话中 source 它。
~/.bashrc
source /usr/share/blesh/ble.sh
配置在 ~/.blerc 文件和 wiki 中有详细说明。稳定的 bleshAUR 包也可用。
命令未找到
pkgfile 包含一个“命令未找到”钩子,当输入未知命令时,它会自动搜索官方仓库。
您需要 source 钩子以启用它,例如
~/.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
禁用终端中的 Ctrl+z
您可以通过像这样包装您的命令来禁用 Ctrl+z 功能(暂停/关闭您的应用程序)
#!/bin/bash trap "" 20 adom
现在,当您不小心在 adomAUR 中按 Ctrl+z 而不是 Shift+z 时,将不会发生任何事情,因为 Ctrl+z 会被忽略。
注销后清屏
在虚拟终端注销后清屏
~/.bash_logout
clear reset
输入路径时自动 cd
Bash 可以在 Shell 中输入路径时自动预置 cd 。例如
$ /etc
bash: /etc: Is a directory
但在向 .bashrc 文件添加一行后
~/.bashrc
... shopt -s autocd ...
您将获得
[user@host ~]$ /etc cd /etc [user@host etc]$
Autojump
autojump-gitAUR 是一个 Python 脚本,它允许通过搜索用户最常访问路径的数据库来进行文件系统导航。
zoxide 是一个替代方案,它具有额外的功能和性能改进,与原始 autojump 相比,可以作为 autojump 的即插即用替换。
防止覆盖文件
对于当前会话,不允许通过 Shell 输出重定向来覆盖现有常规文件
$ set -o noclobber
这与 set -C 相同。
为您的用户永久更改
~/.bashrc
... set -o noclobber
当设置了 noclobber 时,手动覆盖文件
$ echo "output" >| file.txt
使用目录栈进行导航
pushd 和 popd 可用于在切换到目录时将目录推入或弹出到栈中。这对于“回放”您的导航历史记录很有用。
[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。
故障排除
窗口调整时自动换行
调整 终端模拟器大小时,Bash 可能不会收到resize信号。这将导致输入的文本无法正确换行并与提示符重叠。checkwinsize Shell 选项会在每条命令后检查窗口大小,并在必要时更新 LINES 和 COLUMNS 的值。
~/.bashrc
shopt -s checkwinsize
即使设置了 ignoreeof,Shell 也会退出
如果您设置了 ignoreeof 选项,并发现反复按 ctrl-d 导致 Shell 退出,这是因为该选项只允许连续调用此按键绑定 10 次(或者更准确地说,10 个连续的 EOF 字符),之后才会退出 Shell。
要允许更高的值,您必须使用 IGNOREEOF 变量。
例如:
export IGNOREEOF=100
通过分析脚本来检查错误
软件包 shellcheck 分析 bash(和其他 shell)脚本,打印可能的错误,并建议更好的编码方式。
还有同目的的网站 shellcheck.net,它基于此程序。
参见
- Bash Reference Manual,或
/usr/share/doc/bash/bashref.html - Readline Init File Syntax
- The Bourne-Again Shell - The Architecture of Open Source Applications 的第三章
- PS1 generator - 使用直观的 UI 生成您的 .bashrc/PS1 bash 提示符
- 更多有用的 .bashrc 命令