在没有足够权限的情况下执行时 iptables 会返回退出代码 3(而不是 1?),是否有特定原因?

在没有足够权限的情况下执行时 iptables 会返回退出代码 3(而不是 1?),是否有特定原因?

我只是忘记使用sudo

usr@arch ~[0] $ iptables -L
iptables v1.4.21: can't initialize iptables table `filter': Permission
denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.
usr@arch ~[3] $ <---

我的bash PS1提示符回显最后一个命令的退出状态($?)。这iptables 联机帮助页不涉及返回码 3:

各种错误消息被打印到标准错误。正常运行时退出代码为 0。似乎由无效或滥用的命令行参数引起的错误会导致退出代码为 2,其他错误会导致退出代码为 1。

SUSv3/POSIX讨论命令的退出状态1诸如mount- 对于错误情况有 7 种不同的退出状态 - 在没有特权的情况下执行的命令返回 1;其联机帮助页中记录的内容:不正确的调用或权限


问。 那么为什么iptablesmount在这方面有所不同 - 纯粹是特定应用?为什么strace对前者执行 an 输出诸如以下内容:socket(PF_INET, SOCK_RAW, IPPROTO_RAW) = -1 EPERM(不允许操作)- 不应该是 EACCES 吗?为什么跟踪非特权mount调用没有揭示类似的错误并且确实这些对退出状态有影响;或者无论什么原因 -1 都是失败?这3从哪里来?


1.另外:GNU Bash;更普遍;随机的怪异;最近的问题参考代码是特定应用+ 历史/usr/include/sysexits.hETC。

答案1

文档不完整。该代码包含以下内部使用的错误代码列表:

enum xtables_exittype {
    OTHER_PROBLEM = 1,
    PARAMETER_PROBLEM,
    VERSION_PROBLEM,
    RESOURCE_PROBLEM,
    XTF_ONLY_ONCE,
    XTF_NO_INVERT,
    XTF_BAD_VALUE,
    XTF_ONE_ACTION,
};

当它尝试初始化时,它会:

if (!*handle)
    xtables_error(VERSION_PROBLEM,
           "can't initialize iptables table `%s': %s",
           *table, iptc_strerror(errno));

xtables_error打印错误消息并以给定的退出代码退出。

恕我直言,该代码似乎有缺陷,假设这里的失败是由于版本问题而没有检查errno以查看它实际上是EPERM.

答案2

退出代码的唯一规则是 0 表示成功,任何其他值表示失败。这个规则超越了unix:它也是其他操作系统(包括DOS、Windows和许多具有退出代码概念的嵌入式系统,但VMS的做法不同)上的常见约定。在 Unix 系统中,它被嵌入到 shell 的布尔结构 ( if, while, &&, ||, !, set -e, …) 中,make然后是所有标准实用程序。在 POSIX C 程序中,EXIT_SUCCESS为 0 并且EXIT_FAILURE是某个非零值(通常为 1)。

关于失败退出代码的选择,没有规则或普遍惯例。只有少数 POSIX 实用程序强制要求特定的故障状态代码:

  • cmpdiff对于不同的文件返回 1,对于错误情况返回 ≥2。
  • expr如果表达式计算结果为零或 null,则返回 1;如果表达式无效,则返回 2;如果其他错误,则返回 ≥3。
  • grep对于“未找到”返回 1,对于错误情况返回 ≥2。许多搜索命令都遵循这一点(但不是find,如果没有文件匹配则返回 0)。
  • mesg返回 0 表示是,1 表示否,≥2 表示错误。
  • patch如果块被拒绝则返回 1,对于其他错误则返回≥2。
  • sort -c如果文件数据未排序,则返回 1;如果有错误,则返回 ≥2。
  • compresslocaledef为特定错误定义一些小值。

有一个常见但不普遍的观点,即较大的值意味着更严重的失败。对于测试布尔条件的命令,例如grep(此模式是否存在?)和diff(这些文件是否相同),1 表示“否”,较高的值表示错误。此外,从 126 开始的值很少使用,因为它们被烘焙到 shell 中(以及、 、 和commandenvnice126和 127 表示调用外部命令失败,而 128 以上的值表示命令被终止一个信号。nohuptime$?/usr/include/sysexits.h来自sendmail,我只在电子邮件系统中看到过它,特别是诸如procmail 之类的邮件传递代理。

许多程序在任何失败时总是返回 1 或总是返回 2。它恰好iptables定义了一些不同的错误代码。

显示的返回值strace来自系统调用。系统调用返回-1以指示错误并将错误代码存储在errno多变的。 Straceerrno在返回码后显示括号中的值。 EACCES(“权限被拒绝”)和(“不允许操作”)之间的区别EPERM有点微妙;总体思路是EACCES表示目标对象上的权限不允许该操作,而EPERM表示存在其他权限问题(例如根本无法访问该对象,或者该操作仅限于 root)。

相关内容