Should I output program’s name when warning or error occurs

stderrunix-philosophy

If I'm writing a script or a program, should I output to stderr its name together with warning or error message? For example:

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

or:

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

I understand that generally it is just a matter of taste (especially if you write your own stuff for yourself), but I wonder if there's anything conventional to that? I believe most UNIX/Linux utilities write their names when something happens, so it seems to be a good thing, but are there any guidelines or unspoken rules how to do that and how not to?

For example, it's not advisable to install binaries under /usr/bin/, rather under /usr/local/bin/ or something else. Are there similar rules about output to stderr? Should I write the name followed by a colon? Or just "Warning!" and "Error!" words? I couldn't find anything but maybe someone could point me to where to read about it.

This question is a bit about programming practices, but I thought it is more appropriate here rather than on stackoverflow, as it's about UNIX/Linux traditions and not programming in general.

Best Answer

It is common practice to save the 0th argument passed to a C program main and use that as the parameter for perror — for simple programs:

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

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

call that program "foo", and running it illustrates the point:

> ./foo
./foo: Cannot allocate memory

Complicated programs may add to the text (or use only the filename without the path), but keeping the program name lets you find where a misbehaving program came from.

There is no universally accepted scheme for error messages, but some widely-used programs (such as gcc) add a message category such as "Error" or "Warning". Here's an example from one of my build-logs:

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

In this example, gcc separates fields with colons and adds a category "warning" after the filename, line number, column number — and before the actual message. But there are several variations, making it complicated for programs (such as vi-like-emacs) to parse the information.

For compilers, using a category in the message makes it simple to detect the fatal errors (which may not be immediately fatal) and warnings. If your program exits on an error it does not add much to say that some are really warnings and some are errors. But when it behaves differently (or continues to work more or less) the category helps to diagnose the problem encountered.

Related Question