Bash

来自 ArchWiki
(重定向自 Alias

Bash (Bourne-Again SHell) 是由 GNU Project 开发的命令行 Shell/编程语言。它的名字暗示了它的前身,早已被弃用的 Bourne shell。Bash 可以在大多数 类 Unix 操作系统上运行,包括 GNU/Linux

BashArch Linux 上的默认命令行 Shell。

调用

Bash 的行为可能会根据其调用方式而改变。以下是一些不同模式的描述。

如果 Bash 是由 TTY 中的 loginSSH 守护进程或类似方式生成的,则它被认为是登录 Shell。此模式也可以使用 -l/--login 命令行选项启用。

当 Bash 的标准输入、输出和错误连接到终端(例如,在终端模拟器中运行时),并且未使用 -c 选项或 非选项 参数(例如,bash script)启动时,Bash 被认为是交互式 Shell。所有交互式 Shell 都会读取 /etc/bash.bashrc~/.bashrc,而交互式登录 Shell 还会读取 /etc/profile~/.bash_profile

注意: 在 Arch 中,/bin/sh(曾经是 Bourne shell 可执行文件)符号链接到 bash。如果 Bash 以名称 sh 调用,它会尝试模仿历史版本 sh 的启动行为,包括 POSIX 兼容性。

配置文件

Bash 将尝试执行一组启动文件,具体取决于它的调用方式。请参阅 GNU Bash 手册的 Bash Startup Files 部分,以获得完整描述。

文件 描述 登录 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 变量开始[1]

Bash 中的这些 Shell 变量可以导出以成为环境变量

VARIABLE=content
export VARIABLE

或使用快捷方式

export VARIABLE=content

环境变量通常放置在 ~/.profile/etc/profile 中,以便其他 Bourne 兼容的 Shell 可以使用它们。

有关更多通用信息,请参阅 环境变量

命令行

Bash 命令行由名为 Readline 的单独库管理。Readline 提供了 emacsvi 样式的快捷方式,用于与命令行交互,例如在单词基础上前后移动、删除单词等。管理输入命令的 历史记录 也是 Readline 的责任。最后但并非最不重要的一点是,它允许您创建

Tab 补全

Tab 补全是通过按 Tab 键自动完成键入的命令的选项(默认启用)。

单 Tab

可能需要最多按三次 Tab 键才能显示命令的所有可能补全。要减少所需的 Tab 键次数,请参阅 Readline#Faster completion

常用程序和选项

默认情况下,Bash 仅 Tab 补全命令、文件名和变量。软件包 bash-completion 通过为常用命令及其选项添加更专业的 Tab 补全来扩展此功能,可以通过读取 /usr/share/bash-completion/bash_completion(在 Arch 的 /etc/bash.bashrc 中已读取)来启用。使用 bash-completion,正常的补全(例如 ls file.* Tab Tab)行为会有所不同;但是,可以使用 compopt -o bashdefault program 重新启用它们(有关更多详细信息,请参阅 [2][3])。

自定义每个命令

注意: 使用 complete 内置命令可能会与 bash-completion 冲突。

默认情况下,Bash 仅 Tab 补全命令后的文件名。您可以使用 complete -c 将其更改为补全命令名称

~/.bashrc
complete -c man which

或使用 -cf 补全命令名称和文件名

complete -cf sudo

有关更多补全选项,请参阅 bash(1) § Programmable Completion

历史记录

历史记录补全

您可以将向上和向下箭头键绑定到搜索 Bash 的历史记录(请参阅:Readline#HistoryReadline 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

... 并且为了确保,永远销毁您的旧历史文件

$ 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 将您现有的 Shell 历史记录替换为 SQLite 数据库,并记录命令的其他上下文。此外,它还提供通过 Atuin 服务器在机器之间可选且完全加密的历史记录同步。

在同步之前启用 bash 历史记录时间戳 (export HISTTIMEFORMAT="%F %T ")。Atuinblesh-gitAURcmd-wrapped 等工具配合使用良好,可在多台机器上提供增强的终端体验。

别名

alias 是一个命令,它允许用另一个字符串替换一个单词。它通常用于缩写系统命令,或为常用命令添加默认参数。

个人别名可以存储在 ~/.bashrc 或从 ~/.bashrc 读取 的任何单独文件中。系统范围的别名(影响所有用户)属于 /etc/bash.bashrc。有关示例别名,请参阅 [4]

对于函数,请参阅 Bash/Functions

技巧和提示

提示符自定义

请参阅 Bash/Prompt customization

语法高亮和自动建议

ble.sh (Bash Line Editor),打包为 blesh-gitAUR,是一个用纯 Bash 编写的命令行编辑器,它是 GNU Readline 的替代品。它具有许多增强功能,如语法高亮、自动建议、菜单补全、缩写、Vim 编辑模式和钩子函数。其他有趣的功能包括状态行、历史记录共享、右侧提示符、瞬态提示符和 xterm 标题。

安装后,在交互式会话中 读取 它。

~/.bashrc
source /usr/share/blesh/ble.sh

配置在 ~/.blerc 文件和 wiki 中进行了深入解释。稳定的 bleshAUR 软件包也可用。

命令未找到

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#Installation

禁用终端中的 Ctrl+z

您可以通过像这样包装命令来禁用 Ctrl+z 功能(暂停/关闭您的应用程序)

#!/bin/bash
trap "" 20
adom

现在,当您在 adomAUR 中意外按下 Ctrl+z 而不是 Shift+z 时,什么也不会发生,因为 Ctrl+z 将被忽略。

退出登录后清除屏幕

要在虚拟终端上退出登录后清除屏幕

~/.bash_logout
clear
reset

仅输入路径时自动 "cd"

当在 Shell 中仅输入路径时,Bash 可以自动前置 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

使用目录栈进行导航

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

故障排除

窗口调整大小时的行换行

当调整 终端模拟器 大小时,Bash 可能不会收到调整大小信号。这将导致键入的文本无法正确换行并与提示符重叠。checkwinsize Shell 选项在每个命令后检查窗口大小,并在必要时更新 LINESCOLUMNS 的值。

~/.bashrc
shopt -s checkwinsize

即使设置了 ignoreeof,Shell 仍然退出

如果您已设置 ignoreeof 选项,并且发现重复按 ctrl-d 会导致 Shell 退出,那是因为此选项仅允许连续调用此键绑定 10 次(或精确地说是 10 个连续的 EOF 字符),然后才退出 Shell。

要允许更高的值,您必须使用 IGNOREEOF 变量。

例如

export IGNOREEOF=100

通过分析脚本检查错误

软件包 shellcheck 分析 bash(和其他 Shell)脚本,打印可能的错误,并建议更好的编码。

还有一个基于此程序的网站 shellcheck.net,用途相同。

参见

教程

社区

示例