出现警告或错误时是否应该输出程序名称?

gsa*_*ret 13 unix-philosophy stderr

如果我正在编写脚本或程序,是否应该将其名称与警告或错误消息一起输出到 stderr?例如:

./script.sh: Warning! Variable "var" lowered down to 10.
Run Code Online (Sandbox Code Playgroud)

或者:

./prog.py: Error! No such file: "file.cfg".
Run Code Online (Sandbox Code Playgroud)

我知道通常这只是一个品味问题(特别是如果你为自己写自己的东西),但我想知道是否有任何传统的东西?我相信大多数 UNIX/Linux 实用程序在发生某些事情时都会写下自己的名字,所以这似乎是一件好事,但是是否有任何指导方针或潜规则如何做到这一点以及如何做到这一点?

例如,不建议将二进制文件安装在 下/usr/bin/,而应安装在/usr/local/bin/其他地方。是否有关于输出到 stderr 的类似规则?我应该写名字后跟一个冒号吗?或者只是“警告!” 和“错误!” 字?我找不到任何东西,但也许有人可以指出我在哪里可以阅读它。

这个问题有点关于编程实践,但我认为它在这里而不是在stackoverflow上更合适,因为它是关于 UNIX/Linux 传统而不是一般的编程。

Tho*_*key 16

通常的做法是保存传递给 C 程序的第 0 个参数main并将其用作参数perror- 对于简单程序:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    char *foo = malloc(9999999999L);
    if (foo == 0)
        perror(argv[0]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

调用该程序“foo”,并运行它说明了这一点:

> ./foo
./foo: Cannot allocate memory
Run Code Online (Sandbox Code Playgroud)

复杂的程序可能会添加到文本中(或仅使用不带路径的文件名),但保留程序名可以让您找到行为不端的程序的来源。

对于错误消息没有普遍接受的方案,但是一些广泛使用的程序(例如 gcc)添加了诸如“错误”或“警告”之类的消息类别。这是我的一个构建日志中的示例:

compiling fld_def (obj_s)
../form/fld_def.c: In function '_nc_Copy_Argument':
../form/fld_def.c:164:14: warning: cast discards 'const' qualifier from pointer target type [-Wcast-qual]
        res = (TypeArgument *)argp;
              ^
Run Code Online (Sandbox Code Playgroud)

在这个例子中,gcc 用冒号分隔字段,并在文件名、行号、列号之后和实际消息之前添加一个类别“警告”。但是有几种变体,使得程序(例如vi-like-emacs)解析信息变得复杂。

对于编译器,在消息中使用类别可以轻松检测致命错误(可能不是立即致命的)和警告。如果您的程序因错误而退出,则说明有些是真正的警告,有些是错误并没有太大意义。但是当它的行为不同(或或多或少地继续工作)时,该类别有助于诊断遇到的问题。


Kaz*_*Kaz 8

如果一个程序作为脚本的一部分被调用,在该脚本中调用了许多其他程序,并且如果它不打印其名称,那么用户将发现很难(呃)找出错误的来源。

(如果错误是一些可能需要调试的意外内部条件,您需要更多信息:不仅仅是程序名称,还有源文件和行号,可能还有回溯。)