Devo enviar o nome do programa quando ocorrer um aviso ou erro?

13

Se eu estiver escrevendo um script ou programa, devo enviar para stderr seu nome junto com uma mensagem de aviso ou erro? Por exemplo:

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

ou:

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

Entendo que geralmente é apenas uma questão de gosto (especialmente se você escreve suas próprias coisas para si mesmo), mas me pergunto se há algo convencional nisso. Eu acredito que a maioria dos utilitários UNIX / Linux escreve seus nomes quando algo acontece, então parece ser uma coisa boa, mas existem diretrizes ou regras tácitas sobre como fazer isso e como não fazer?

Por exemplo, não é aconselhável instalar os binários abaixo /usr/bin/, abaixo de /usr/local/bin/ou em outra coisa. Existem regras semelhantes sobre a saída para o stderr? Devo escrever o nome seguido de dois pontos? Ou apenas "Aviso!" e "Erro!" palavras? Não consegui encontrar nada, mas talvez alguém pudesse me indicar onde ler sobre isso.

Essa pergunta é um pouco sobre práticas de programação, mas achei mais apropriada aqui do que no stackoverflow , pois trata das tradições UNIX / Linux e não da programação em geral.

gsarret
fonte
5
O nome do programa pode ajudar na depuração aleatória no such filede quem sabe qual programa em um foo | bar | bazpipeline.
thrig
@thrig Obrigado, bom ponto. A minha não deveria ser canalizada, mas quem sabe. Acho que é melhor seguir o comportamento padrão.
gsarret

Respostas:

16

É prática comum salvar o argumento passado em um programa C maine usá-lo como parâmetro para perror- para programas simples:

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

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

chame esse programa de "foo" e executá-lo ilustra o ponto:

> ./foo
./foo: Cannot allocate memory

Programas complicados podem ser adicionados ao texto (ou usar apenas o nome do arquivo sem o caminho), mas manter o nome do programa permite descobrir de onde veio um programa que se comporta mal.

Não existe um esquema universalmente aceito para mensagens de erro, mas alguns programas amplamente usados ​​(como o gcc) adicionam uma categoria de mensagem como "Erro" ou "Aviso". Aqui está um exemplo de um dos meus logs de construção:

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

Neste exemplo, o gcc separa campos com dois pontos e adiciona uma categoria "aviso" após o nome do arquivo, número da linha, número da coluna - e antes da mensagem real. Mas existem várias variações, tornando complicado para programas (como o vi-like-emacs ) analisar as informações.

Para compiladores, o uso de uma categoria na mensagem simplifica a detecção de erros fatais (que podem não ser imediatamente fatais ) e avisos. Se o seu programa sair com um erro, não há muito a dizer que alguns são realmente avisos e outros são erros. Porém, quando se comporta de maneira diferente (ou continua a funcionar mais ou menos), a categoria ajuda a diagnosticar o problema encontrado.

Thomas Dickey
fonte
Obrigado por um exemplo, eu entendi. E quanto a "Erro" e "Aviso", eles desorganizam a saída?
gsarret
Sua última edição - exatamente o que eu estava pensando! De que serve se ele sair logo após a mensagem de erro? Obrigado novamente.
gsarret
8

Se um programa for chamado como parte de um script no qual muitos outros programas são chamados, e se não imprimir seu nome, os usuários terão dificuldade em descobrir de onde vem o erro.

(Se o erro for uma condição interna inesperada que pode exigir depuração, você deseja obter ainda mais informações: não apenas o nome do programa, mas um arquivo de origem e número de linha e, possivelmente, um rastreamento posterior.)

Kaz
fonte
Obrigado. Eu normalmente escrevo programas para mim mesmo (simulação numérica), de modo que há apenas um usuário; no entanto, posso compartilhá-los um dia. Eles também não são tão complexos (bem, pelo menos ainda), por isso não há problema em encontrar a fonte do erro, mas obrigado pela dica, pode ser útil no futuro.
gsarret