É seguro que você pretenda que o formato seja passado como argumento. Mas você tem que lembrar quando usar a função que é o formato. Então, talvez você deva nomear sua função errorf
como um lembrete.
Se você usou como:
error "invalid arg: $arg"
Você causaria problemas como valores de $arg
como %99999999s
O ideal é que você queira dizer ao shellcheck para ignorar esse uso de printf
e para sinalizar os usos de seu printf
, onde o primeiro argumento contém variáveis.
Algumas notas:
- Como você está invocando
printf
duas vezes, serão pelo menos 2write()
de chamadas do sistema. É improvável que faça alguma diferença e observe que algumas implementaçõesprintf
comobash
farão várias chamadas do sistema em algumas circunstâncias também. O tipo de problema em que estou pensando são as duas partes da mensagem de erro sendo entrelaçadas com a saída de outro comando em execução em paralelo. -
Em
error "%s\n" error1 error2
, o prefixo será gerado apenas para o primeiro erro. Tudo bem se é assim que você quer fazer. Você também pode fazer:errorf() { printf "utility: ERROR: $@" >&2; }
para que o prefixo seja prefixado ao formato, para que seja emitido toda vez que o formato for reutilizado (o que também resolveria o problema múltiplo
write()
).Isso, no entanto, não funcionaria se você quisesse que
utility
fosse uma variável.PROG_NAME=${0##*/} errorf() { printf >&2 "$PROG_NAME: ERROR: $@"; }
$0
contém%
ou\
.e
PROG_NAME=${0##*/} errorf() { format=$1; shift printf >&2 "%s: ERROR: $format" "$PROG_NAME" "$@" }
%<n>$d
(não que eu recomendaria usar aqueles que não são portáteis)).Não consigo pensar em nenhum trabalho fácil além de escapar do
\
e%
manualmente no$PROG_NAME
, e mesmo isso não é fácil, já que com muitas implementaçõesprintf
, você também precisaria para escapar dos0x5c
bytes encontrados em outros caracteres que não sejam\
(para os conjuntos como BIG5 ou GB18030 que possuem algum).