在 Bash Shell 中使用 set
Niraj Menon
2023年1月30日
Bash shell 包含几个有用的内置命令来操作当前运行的 shell 会话的环境。内置的 set
命令提供了查看和更改 shell 环境变量和选项的能力。
本教程讨论了 set
命令的使用范围以及如何有效地编写 Bash 脚本来设置良好的环境选项。
在 Bash 中使用 set -x
进行命令跟踪
默认情况下,单独运行 set
命令将返回当前设置的变量及其值的列表,包括 Bash 可执行文件位置、版本信息和 PATH 等环境变量。
该命令的使用是当你查看执行的命令时。如果你是程序员,这可以帮助你调试 Bash 脚本以查看它们是否在特定命令上失败。
为此,请执行 set -x
或 set -o xtrace
,这将打开命令跟踪。虽然命令本身不输出任何内容,但后续命令将在执行前打印出来。在命令中使用大括号扩展(最近的 Bash 功能)很有帮助。
如果你有删除编号 TXT 文件的命令,启用 set
命令跟踪将显示大括号的扩展形式以及该目录中的所有 TXT 文件。
user@linux:~$ set -x
user@linux:~$ cd /tmp
+ cd /tmp
user@linux:~$ # example of expansion (and comments do not print out in traces)
user@linux:~$ touch {1..5}.txt
+ touch 1.txt 2.txt 3.txt 4.txt 5.txt
user@linux:~$ rm -f *.txt
+ rm -f *.txt
user@linux:~$ # however, asterisk globs do not expand.
Bash 中 set
的其他有用选项
set
命令为类似于命令跟踪的 shell 操作提供了许多其他互斥选项,例如不执行命令、将命令行更改为 Emacs 样式的编辑器、发生错误时打印回溯等等。
请记住,要打开一个选项,你必须使用 set -o <option_name>
和 set +o <option_name>
将其关闭。
下面解释了这些选项的完整列表,信息来自 GNU manual for the set built-in。
allexport
- 如果你有一个设置环境变量的 Bash 脚本,并且你希望这些变量可用于当前 shell 和任何后续子 shell,set -a
或set -o allexport
会导致这些要导出并可供这些 shell 上下文使用的变量。braceexpand
- 大括号扩展允许我们将一对数字的常量集合扩展为这些数字范围的空格分隔字符串。如果你想在 shell 中使用较低的命令评估大括号,则关闭此选项将禁用大括号扩展。Emacs
- 为熟悉它的人启用基于 emacs 的命令行编辑。errexit
- 如果 Bash 脚本中的命令以非零状态码退出,则整个脚本将停止。可以通过将失败的命令与返回零退出代码的第二个命令进行 OR 运算来防止脚本过早退出。errtrace
- 如果程序以非零状态码退出,则会打印出对失败命令的回溯。hashall
- 在环境 PATH 中搜索命令位置时跟踪它们。它将命令路径缓存在一个位置,以便更快地搜索和执行。histexpand
- 扩展!
字符串中的字符作为历史替换功能。如果你在使用!
时遇到问题字符串中的字符并且不做太多历史替换工作,你可以安全地关闭它。历史
- 这是一项重要功能,可让你维护以前执行的命令列表。ignoreeof
- EOF 字符(由 Ctrl-D 提供)通常退出 Bash shell 或接受输入的命令。禁用此选项会导致 EOF 被忽略,这可能会破坏一些只接受 EOF 的命令。Monitor
- 启用作业控制,使在后台运行的进程在完成执行时打印出它们的退出代码。在后台进程完成时检查它们很有用。noclobber
- 防止 Bash 重定向实用程序,例如>&、<>
截断现有文件。如果你在测试时处理真实的日志文件并且不希望意外删除现有日志,这将非常方便。noexec
- 打印出命令但不执行它们。如果在脚本中使用,noexec
可以跳过某些命令并通过在某些点打开和关闭它们来执行其他命令。noglob
- 防止 glob 的扩展(即 *.txt)。Notify
- 当与monitor
一起使用时,notify
会立即打印出后台作业状态代码,而不是等待下一个 shell 提示。nounset
- 如果未设置变量并尝试读取其值,则返回错误代码。onecmd
- 读取并执行下一条命令后退出。
如果你想阅读更多选项,请参阅上面的手册。希望这些选项可以改善你的 Bash 编程体验。
如果你想从命令行再次了解这些选项,请尝试运行 help set
。我们还推荐 Linux 文档项目的页面以获取有关 set
命令的更多信息。