出现警告或错误时,我应该输出程序名称吗?


13

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

./script.sh: Warning! Variable "var" lowered down to 10.

要么:

./prog.py: Error! No such file: "file.cfg".

我了解通常这只是一个口味问题(尤其是您是否自己编写自己的东西),但是我想知道是否有任何常规做法?我相信大多数UNIX / Linux实用程序都会在发生某些情况时写下它们的名称,所以这似乎是一件好事,但是是否有任何准则或不为人知的规则如何做到这一点以及如何做到这一点呢?

例如,不建议将二进制文件安装/usr/bin//usr/local/bin/或下。关于输出到stderr是否有类似的规则?我应该在名字后面加上冒号吗?或只是“警告!” 和“错误!” 话?我什么也找不到,但也许有人可以指出我的位置。

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


5
程序名称可以帮助调试no such file谁知道foo | bar | baz管道中的哪个程序的随机变量。
thrig

@thrig谢谢,很好。我的不该用管道输送,但谁知道。猜测最好坚持标准行为。
gsarret's

Answers:


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;
}

将该程序称为“ foo”,并运行它说明了这一点:

> ./foo
./foo: Cannot allocate memory

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

对于错误消息,没有公认的方案,但是某些广泛使用的程序(例如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;
              ^

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

对于编译器,在消息中使用类别可以简化检测致命错误(可能不是立即致命)和警告的过程。如果您的程序由于错误而退出,则并没有多说什么确实是警告而有些是错误。但是,当其行为有所不同(或继续或多或少地起作用)时,该类别有助于诊断遇到的问题。


谢谢你的例子,我明白了。“错误”和“警告”又如何,它们会使输出混乱吗?
gsarret's

您的最后编辑-正是我在想的!如果在err消息后立即退出,有什么用?再次感谢。
gsarret's

8

如果某个程序作为脚本的一部分被调用,而其他许多程序也在其中被调用,并且它没有显示其名称,则用户将很难发现错误的出处。

(如果错误是某些意外的内部情况,可能需要调试,则您需要更多信息:不仅是程序名称,还包括源文件和行号,以及可能的回溯信息。)


谢谢。我通常为自己编写程序(数值模拟),因此只有一个用户,但是有一天我可能会共享它们。它们也不是那么复杂(至少到目前为止),因此找到错误源没有问题,但是感谢您的提示,将来可能会有用。
gsarret's
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.