Bash

来自 ArchWiki
(重定向自 Bashrc

Bash (Bourne-Again SHell) 是一个由 GNU 项目开发的命令行 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 启动文件 部分。

文件 描述 登录 Shell (参见注释) 交互式,非登录 Shell
/etc/profile Source 应用程序设置在 /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 仅在命令后补全文件名。您可以将其更改为使用 complete -c 补全命令名称

~/.bashrc
complete -c man which

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

complete -cf sudo

有关更多补全选项,请参阅 bash(1) § 可编程补全

历史记录

历史记录补全

您可以绑定向上和向下箭头键以搜索 Bash 的历史记录(请参阅:Readline#HistoryReadline 初始化文件语法

~/.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 编辑模式和 hook 函数。其他有趣的功能包括状态行、历史记录共享、右侧提示符、瞬态提示符和 xterm 标题。

安装后,在交互式会话中 执行 它。

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

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

命令未找到

pkgfile 包括一个 “command not found” hook,当输入无法识别的命令时,它将自动搜索官方存储库。

您需要 执行 hook 以启用它,例如

~/.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,用途相同。

参见

教程

社区

示例