我是一个替代品的作者find
,它试图与 POSIX(以及许多流行的扩展)兼容。最近,我注意到我的实用程序的行为与其他find
实现之间存在差异,我想知道 POSIX 是否允许我的行为或者我是否需要更改它。
$ find . -exec /no/such/file {} \;
find: ‘/no/such/file’: No such file or directory
$ echo $?
0
$ bfs . -exec /no/such/file {} \;
bfs: error: .: -exec /no/such/file: No such file or directory.
$ echo $?
1
在这种情况下,至少 GNU、busybox 和 FreeBSD 都发现退出状态为 0。我的实现将execv()
错误从fork()
ed 子级传播到父级,而其他实现似乎直接从子级打印错误而不告诉父级。
我问这个问题的原因,而不是仅仅改变行为以匹配其他问题,是因为在使用posix_spawn()
.的实现posix_spawn()
允许将execv()
错误传播到errno
父级中,并且例如glibc
和musl
都执行此操作。似乎不可能判断错误是发生在 之前还是之后,并且可能在(例如)fork()
之前发生的错误应该导致非零退出状态。fork()
ENOMEM
我已阅读POSIX 规范find
,但这里没有详细介绍。但是,我听说其他地方记录了可能相关的其他规则。例如,我听说如果一个实用程序打印到标准错误,它也必须以非零退出代码退出,这似乎意味着其他find
s 不兼容。但我不确定这个措辞在哪里,或者它是否真的存在。
答案1
POSIX 规范find
在其STDERR
部分中表示,
否则,标准错误应仅用于诊断消息。
(“否则”跟在 的描述后面-ok
,此处与此无关。)
这需要根据以下情况来理解实用程序描述默认值,其中指定
当本节被列为“标准错误仅用于诊断消息”时,意味着除非另有说明,只有当退出状态指示发生错误并且实用程序的使用方式如本卷 POSIX.1-2017 中所述。
所以这不是真的全部POSIX 兼容实用程序仅在退出时状态指示错误时才允许输出到标准错误;但对于具体提及的实用程序来说确实如此,其中包括find
.