Должен ли я выводить имя программы при появлении предупреждения или ошибки?

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? Должен ли я написать имя с двоеточием? Или просто "Предупреждение!" и "Ошибка!" слова? Я ничего не мог найти, но, возможно, кто-то мог бы указать мне, где читать об этом.

Этот вопрос немного о методах программирования, но я подумал, что он более уместен здесь, а не над стековым потоком , поскольку речь идет о традициях UNIX / Linux, а не о программировании в целом.

gsarret
источник
5
Имя программы может помочь отладке случайного числа no such fileот того, кто знает, какая программа в foo | bar | bazконвейере.
августа
@ thrig Спасибо, хорошая мысль. Шахта не должна быть водопроводной, но кто знает. Думаю, лучше придерживаться стандартного поведения.
gsarret

Ответы:

16

Обычной практикой является сохранение 0-го аргумента, передаваемого программе на C, 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
Ваше последнее редактирование - именно то, о чем я думал! Какая польза, если он все равно выходит сразу после сообщения об ошибке? Еще раз спасибо.
gsarret
8

Если программа вызывается как часть сценария, в котором вызываются многие другие программы, и если она не печатает свое имя, то пользователям будет трудно (э) выяснить, откуда возникла ошибка.

(Если ошибка является неожиданным внутренним условием, которое может потребовать отладки, вам нужна дополнительная информация: не только имя программы, но и исходный файл и номер строки и, возможно, обратный след.)

Kaz
источник
Благодарю. Я обычно пишу программы для себя (численное моделирование), поэтому есть только один пользователь, однако я могу поделиться им однажды. Они также не так сложны (по крайней мере, пока), поэтому нет проблем с поиском источника ошибки, но спасибо за подсказку, которая может пригодиться в будущем.
gsarret