退出代码或退出状态告诉我们最后执行的命令的状态。命令是成功执行还是以错误退出。这些都是可以在命令终止后获得的。
其原理是程序返回退出代码 0 表明程序成功执行且没有问题。代码 1 或任何非 0 的值都被视为不成功。除了 0 和 1 之外,还有更多退出代码,我将在本文中介绍。
Linux shell 退出代码
退出代码 | 代码的含义 |
---|---|
0
|
命令执行没有错误 |
1
|
一般错误代码 |
2
|
命令(或参数)使用不正确 |
126
|
权限被拒绝(或)无法执行 |
127
|
未找到命令,在 PATH 未找到 |
128+n
|
通过命令传递从外部信号终止,或者遇到致命错误 |
130
|
通过 Ctrl+C 或 SIGINT 终止(终止代码 2 或键盘中断) |
143
|
由 SIGTERM 终止(默认终止) |
255/*
|
退出代码超出 0-255 范围,反转错误 |
查看命令程序的退出代码
先前执行的命令的退出代码存储在特殊变量 $?
。您可以通过运行命令 echo $?
来查看退出代码:
echo $?
这将在我们所有的演示中用于查看退出代码。值得一提的是,exit 命令支持直接使用与上一个执行的命令相同的退出代码。
退出代码 0
退出代码 0
表示命令执行无误。这是运行命令程序的理想情况。例如,让我们运行neofetch 命令查看系统信息。
neofetch
echo $?
.-/+oossssoo+/-. myfreax@myfreax
`:+ssssssssssssssssss+:` ---------------
-+ssssssssssssssssssyyssss+- OS: Ubuntu 20.04.6 LTS x86_64
.ossssssssssssssssssdMMMNysssso. Kernel: 5.15.0-76-generic
/ssssssssssshdmmNNmmyNMMMMhssssss/ Uptime: 3 hours, 41 mins
+ssssssssshmydMMMMMMMNddddyssssssss+ Packages: 2316 (dpkg), 14 (snap)
/sssssssshNMMMyhhyyyyhmNMMMNhssssssss/ Shell: zsh 5.8
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Resolution: 2560x1440
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ DE: GNOME
ossyNMMMNyMMhsssssssssssssshmmmhssssssso WM: Mutter
ossyNMMMNyMMhsssssssssssssshmmmhssssssso WM Theme: WhiteSur-Light
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ Theme: WhiteSur-Light [GTK2/3]
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Icons: WhiteSur [GTK2/3]
/sssssssshNMMMyhhyyyyhdNMMMNhssssssss/ Terminal: gnome-terminal
+sssssssssdmydMMMMMMMMddddyssssssss+ CPU: Intel i5-6500 (4) @ 3.600GHz
/ssssssssssshdmNNNNmyNMMMMhssssss/ GPU: NVIDIA GeForce GTX 1050
.ossssssssssssssssssdMMMNysssso. Memory: 5710MiB / 7874MiB
-+sssssssssssssssssyyyssss+-
`:+ssssssssssssssssss+:`
.-/+oossssoo+/-.
此退出代码 0
意味着指定的命令已成功执行,仅此而已。
退出代码 1
退出代码 1
也是一种常见的代码。它通常意味着命令因一般错误而终止。例如,使用没有 sudo 权限的包管理器会生成代码 1
。
你可以在 Arch Linux ,尝试运行命令 pacman -Sy
,命令将会打印错误代码 1, 意味着运行命令 pacman -Sy
导致错误。
pacman -Sy
echo $? # 0
如果您在基于 Ubuntu 的发行版不带 sudo 的 apt update
命令,echo $?
则会打印错误代码 100。 这是在没有权限的情况运行 apt 命令的错误代码。
这不是一个标准化的错误代码,而是 apt 特有的错误代码。但我们也可以将其理解为不允许操作。
除此以外,还有一种特殊的情况也会以错误代码 1 退出。那就是在 Shell 的除法中,当使用 0 作为除数时,echo $?
命令打印错误代码 1。
let a="1/0" #zsh: division by zero
echo $?
退出代码 2
当执行的命令有语法错误时,会给出退出代码 2。滥用命令参数也会导致此错误。通常表明该命令由于使用不正确而无法执行。
例如,我们向应该有一个连字符 -
的选项添加两个连字符。echo $?
命令将会打印错误代码 2。
grep --z file.txt
echo $?
还有一种情况是,当因为权限被拒绝时,也会返回错误代码 2。例如使用 ls 命令访问 /root 目录,echo $?
命令将会打印错误代码 2。
ls /root # ls: cannot open directory '/root': Permission denied
echo $? # 2
退出代码 126
126 是一个特殊的退出代码,因为它用于指示由于权限错误而未执行命令或脚本。当您尝试在未授予执行权限的情况执行 shell 脚本时,可能会出现此错误。
./script.sh # bash: ./script.sh: Permission denied
echo $? # 126
请注意,此退出代码仅在没有足够权限的情况执行脚本 / 命令时出现,这与一般的权限被拒绝错误不同。
因此,不要将其与在退出代码 2 中看到的 ls 命令访问根目录示例混淆。运行 ls 命令访问根目录的权限问题是来自 ls 命令尝试执行的目录。在这里,权限问题来自脚本本身。
退出代码 127
这是另一种常见的情况。退出代码 127 指的是命令未找到。当执行的命令中有拼写错误或所需的可执行文件不在 $PATH 环境变量时,通常会发生这种情况。
例如,当我们没有使用相对路径或者绝对路径运行脚本时,则经常会看到此错误。
./script.sh # 正常执行
script.sh # bash: script.sh: command not found
echo $? # 127
或者当您尝试运行的可执行文件在 $PATH
环境变量指定的目录中未找到。您可以可执行文件所在的目录添加到 PATH 变量来解决此问题。
当您键入不存在的命令时,您也会收到此退出代码。
unmount -a # bash: unmount command not found
echo $? # 127
退出代码 128+n
当应用程序或命令因致命错误而终止或执行失败时,将生成与 128 相邻的代码 128+n,其中 n 是信号编号。此处的 n 值适用于所有类型的终止代码,例如 SIGTERM
、SIGKILL
等。
代码 130 或 SIGINT
SIGINT
或键盘中断信号是通过终止信号 2 或 Ctrl+C 中断进程而引发的。由于终止信号为 2,因此我们得到代码 130 (128+2)。
lxappearance # 打开任意一个 GUI 应用,通过终端
echo $? # 130
代码 137 或 SIGKILL
立即终止进程的 SIGKILL
终止信号 9。这是终止应用程序时应使用的最后一种方法。由于终止信号为 9 (128+9),因此命令 echo $?
打印退出代码 137。
lxappearance # 打开任意一个 GUI 应用,通过终端
pkill lxappearance #在另一个终端,终止 lxappearance GUI 应用
echo $? # 130 在打开的 lxappearance 应用在同一个终端运行此命令
超过 255 的错误代码
最新版本的 Bash 保留原始退出代码值,甚至超过 255,但通常,如果代码超过 255,则它会被反转。
也就是说,代码 256 变为 0,257 变为 1,383 变为 127,依此类推。为了确保更好的兼容性,请将退出代码保持在 0 到 255 之间。
结论
至此,您已了解 Linux shell 的退出代码。使用它们可以方便地解决各种问题。如果您在 shell 脚本中使用这些代码,请确保您了解每个代码的含义,则可以更轻松地进行调试。