Linux 中退出码的含义

Linux 中退出码的含义

揭开 Linux 中退出码的神秘面纱。了解什么是退出码,以及为什么和如何使用它们。

退出码(退出状态)可以告诉我们最后一次执行的命令的状态。在命令结束以后,我们可以知道命令是成功完成的还是以错误结束的。

其基本思想是,程序返回退出代码 0 时表示执行成功,没有问题。代码 10 以外的任何代码都被视为不成功。

退出码除了 0 和 1 外还有很多值,我将在本文介绍它们。

Linux Shell 中的各种退出码

我们来快速了解一下 Linux Shell 中的主要退出码:

退出码 解释
0 命令成功执行
1 通用错误代码
2 命令(或参数)使用不当
126 权限被拒绝(或)无法执行
127 未找到命令,或 PATH 错误
128+n 命令被信号从外部终止,或遇到致命错误
130 通过 Ctrl+CSIGINT 终止(终止代码 2 或键盘中断
143 通过 SIGTERM 终止(默认终止
255/* 退出码超过了 0-255 的范围,因此重新计算(LCTT 译注:超过 255 后,用退出码对 256 取模)

? 130SIGINT^C)和 143SIGTERM)等终止信号是非常典型的,它们属于 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,表示你是在没有权限的情况下运行 apt100 不是标准错误码,而是 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 包括所有类型的终止代码,如 SIGTERMSIGKILL 等。

退出码 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 会变成 0257 会变成 1383 会变成 127,以此类推。为确保更好的兼容性,请将退出码保持在 0255 之间。

结语

希望你对 Linux Shell 中的退出码有所了解。在排查各种问题时,使用它们会非常方便。

如果你要在 Shell 脚本中使用这些代码,请确保你了解每个代码的含义,以便更容易地排除故障。

这就是本文的全部内容。如有遗漏,请在评论区告诉我。

(题图:MJ/719ff711-1b9f-4aa9-a82e-980704acbdd8)


via: https://itsfoss.com/linux-exit-codes/

作者:Pranav Krishna 选题:lkxed 译者:lxbwolf 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出