Como você encontra o número da linha no Bash onde ocorreu um erro?
Exemplo
Eu crio o seguinte script simples com números de linha para explicar o que precisamos. O script copiará os arquivos de
cp $file1 $file2
cp $file3 $file4
Quando um dos cp
comandos falhar, a função sairá com exit 1 . Queremos adicionar à função a capacidade de também imprimir o erro com o número da linha (por exemplo, 8 ou 12).
Isso é possível?
Exemplo de script
1 #!/bin/bash
2
3
4 function in_case_fail {
5 [[ $1 -ne 0 ]] && echo "fail on $2" && exit 1
6 }
7
8 cp $file1 $file2
9 in_case_fail $? "cp $file1 $file2"
10
11
12 cp $file3 $file4
13 in_case_fail $? "cp $file3 $file4"
14
Em vez de usar sua função, eu usaria este método:
Isso funciona capturando o ERR e, em seguida, chamando a
failure()
função com o número da linha atual + comando bash que foi executado.Exemplo
Aqui não tomei nenhum cuidado para criar os arquivos,
f1
,f2
,f3
, ouf4
. Quando executo o script acima:Ele falha, relatando o número da linha mais o comando que foi executado.
Além de
LINENO
conter o número da linha atual, existem as matrizesBASH_LINENO
andFUNCNAME
(eBASH_SOURCE
) que contêm os nomes das funções e os números das linhas de onde são chamadas.Então você poderia fazer algo assim:
Executando isso imprimiria
Se você usar
set -e
, outrap ... ERR
para detectar erros automaticamente, observe que eles têm algumas ressalvas. Também é mais difícil incluir uma descrição do que o script estava fazendo no momento (como você fez no seu exemplo), embora isso possa ser mais útil para um usuário comum do que apenas o número da linha.Veja, por exemplo, estes para os problemas com
set -e
e outros:Bash tem uma variável embutida
$LINENO
que é substituída pelo número da linha atual quando em uma instrução, então você pode fazerVocê também pode tentar usar
trap ... ERR
o que é executado quando um comando falha (se o resultado não for testado). Por exemplo:Então, se um comando como
cp $file1 $file2
falhar, você receberá a mensagem de erro com o número da linha e uma saída. Você também encontrará o comando com erro na variável$BASH_COMMAND
(embora não em qualquer redirecionamento, etc.).Eu decidi usar o seguinte, que inclui um rastreamento de pilha como
list of fns [list of line numbers]
se o script estivesse em uma função ou o número da linha do script caso contrário. Os agradecimentos também vão para as respostas anteriores, que expandi após algumas experiências para lidar com scripts baseados em fn e não baseados em fn.Então, uma simples falha de comando, se parece com:
E funções aninhadas (onde hello1 chama hello2):
Eu reporto o status de saída nos momentos estranhos em que ele fornece informações extras e, ao contrário de todos os outros, quero o nome do caminho completo do script.
Mais trabalho será necessário para relatar a saída devido a sinais.