退出码(退出状态)可以告诉我们最后一次执行的命令的状态。在命令结束以后,我们可以知道命令是成功完成的还是以错误结束的。
其基本思想是,程序返回退出代码 0
时表示执行成功,没有问题。代码 1
或 0
以外的任何代码都被视为不成功。
退出码除了 0 和 1 外还有很多值,我将在本文介绍它们。
Linux Shell 中的各种退出码
我们来快速了解一下 Linux Shell 中的主要退出码:
退出码 | 解释 |
| 命令成功执行 |
| 通用错误代码 |
| 命令(或参数)使用不当 |
| 权限被拒绝(或)无法执行 |
| 未找到命令,或 |
| 命令被信号从外部终止,或遇到致命错误 |
| 通过 |
| 通过 |
| 退出码超过了 0-255 的范围,因此重新计算(LCTT 译注:超过 255 后,用退出码对 256 取模) |
📋
130
(SIGINT
或^C
)和143
(SIGTERM
)等终止信号是非常典型的,它们属于128+n
信号,其中n
代表终止码。
在简单了解了退出码之后,我们来看看它们的用法。
获取退出码
前一个命令执行的退出码存储在 特殊变量 $?
中。你可以通过运行以下命令来获取:
echo $?
我们在所有演示中都将使用它来获取退出代码。
请注意,exit
命令支持以带着前一条命令相同的退出码退出。
退出码 0
退出码 0
表示命令执行无误,这是完成命令的理想状态。
例如,我们运行这样一条基本命令
neofetch
echo $?
这个退出码 0
表示特定命令已成功执行,仅此而已。让我们再演示几个例子。
你可以尝试 终止一个进程;它也会返回代码 0
。
pkill lxappearance
查看文件内容也会返回退出码 0,这仅意味着 cat
命令执行成功。
退出码 1
退出码 1
也很常见。它通常表示命令以一般错误结束。
例如,在没有 sudo 权限的情况下使用 软件包管理器,就会返回代码 1
。在 Arch Linux 中,如果我运行下面的命令:
pacman -Sy
它会返回 1
, 表示上一条命令运行出错。
exit code 1 (impermissible operation resulted in this code)
📋 如果你在基于 Ubuntu 的发行版中尝试这样做(不使用
sudo
执行apt update
),运行后会得到错误码100
,表示你是在没有权限的情况下运行apt
。100
不是标准错误码,而是apt
特有的错误码。
虽然这是一般的理解,但我们也可以将其解释为 “不被允许的操作”。
除以 0
等操作也会返回错误码 1
。
Division by zero results in code 1
退出码 2
这个退出码出现在当执行的命令有语法错误时。滥用命令参数也会导致此错误。
一般来说,它表示由于使用不当,命令无法执行。
例如,我在一个本应只有一个连字符的选项上添加了两个连字符,那么此时会出现退出码 2。
grep --z file.txt
Invalid argument resulted in exit code 2
当权限被拒绝时,比如访问 /root
文件夹,就会出现错误码 2
。
Permission denied gives out code 2
退出码 126
126 是一个特殊的退出码,它用于表示命令或脚本因权限错误而未被执行。
当你尝试执行没有执行权限的 Shell 脚本时,就会出现这个错误。
请注意,该退出码只出现在没有足够权限的脚本或命令的“执行”中,这与一般的权限被拒绝错误不同。
因此,不要把它与你之前看到的退出码为 2
的示例混淆。在那个示例中,运行的是 ls
命令,权限问题出自它试图执行的目录。而本例中权限问题来自脚本本身。
退出码 127
这是另一个常见的退出码。退出码 127
指的是“未找到命令”。它通常发生在执行的命令有错别字或所需的可执行文件不在 $PATH
变量中时。
例如,当我尝试执行一个不带路径的脚本时,经常会看到这个错误。
Script executed without the path gives "command not found" or code 127
当你想运行的可执行文件不在 $PATH
变量中时,也会出现退出码 127
。你可以通过 在 PATH 变量中添加命令的目录 来纠正这种情况。
当你输入不存在的命令时,也会得到这样的退出码。
Unmount is not a command, and Screenfetch is not installed, which resulted in code 127
退出码 128+n 系列
当应用程序或命令因致命错误而终止或执行失败时,将产生 128 系列退出码(128+n
),其中 n
为信号编号。
n
包括所有类型的终止代码,如 SIGTERM
、SIGKILL
等。
退出码 130 或 SIGINT
在通过终止信号 2
或按下 Ctrl+C
中断进程时,会发出 SIGINT
(键盘中断信号)。
因为终止信号是 2
,所以我们得到的退出码是 130
(128+2)。下面的视频演示了 lxappearance
的中断信号。
退出码 137 或 SIGKILL
SIGKILL
(立即终止信号)表示终止信号 9
。这是终止应用程序时最不应该使用的方法。
因为终止信号为 9
,因此我们得到的退出代码为 137
(128+9)。
退出码 143 或 SIGTERM
SIGTERM
是进程在未指定参数的情况下被杀死时的默认行为。
SIGTERM
的终止信号为 15
,因此该信号的退出码为 143
(128+15)。
还有一些你以前可能不知道的终止信号,它们也有自己类似的退出码。你可以在这里查看它们:
📋 请注意,如果进程在启动它的同一会话中终止,这些信号可能不会出现。如果要重现这些信号,请从不同的 shell 终止。
就个人而言,信号
128
是无法重现的。
当退出码超过了 255 会怎样?
最新版本的 Bash 甚至保留了超过 255 的原始退出码的值,但一般来说,如果代码超过 255,就会被重新计算。
也就是说,代码 256
会变成 0
,257
会变成 1
,383
会变成 127
,以此类推。为确保更好的兼容性,请将退出码保持在 0
至 255
之间。
结语
希望你对 Linux Shell 中的退出码有所了解。在排查各种问题时,使用它们会非常方便。
如果你要在 Shell 脚本中使用这些代码,请确保你了解每个代码的含义,以便更容易地排除故障。
这就是本文的全部内容。