A maneira mais fácil de encontrar aspas faltando em um bash um script?

5

Eu tenho um script bash que atualmente tem mais de 700 linhas. Depois de uma rodada particularmente longa de edição, agora erros assim:

./run_me.sh: line 693: unexpected EOF while looking for matching '''
./run_me.sh: line 702: syntax error: unexpected end of file

No entanto, não há nada errado que eu possa ver com a linha 693. Não há nem mesmo uma citação sobre isso.

Eu tentei executar bash -x run_me.sh e posso ver a última linha sendo executada, mas não há nada de errado com essa linha (e o código entre essa linha e 693 é, efetivamente, a maior parte do código).

Eu posso comentar partes inteiras do código, mas é mais provável que eu veja erros devido à falta de funções, etc, em vez do erro EOF que estou recebendo.

Então, como alguém deve encontrar a cotação faltante, se o número da linha for informado incorretamente?

(Por que o número da linha do bash está tão longe do relatório?)

Editar

Incidentalmente, eu encontrei meu erro particular (comentando por faixas), que na verdade era um } ausente em uma expansão de variável em um número de linha arbitrário nem perto da linha indicada pela mensagem de erro - realce de sintaxe baseado em citações não ajuda aqui, por exemplo com a chave ausente em "${MY_ARRAY[@]" (deve ser "${MY_ARRAY[@]}" ).

    
por jimbobmcgee 25.05.2015 / 00:42

4 respostas

7

Uma abordagem de baixa tecnologia é

tr -cd "'\n" < run_me.sh | awk 'length%2==1 {print NR, $0}'

O tr exclui todos os caracteres, exceto as aspas simples e as novas linhas, e o awk identifica as linhas que possuem números ímpares de caracteres (isto é, cotações não correspondentes). Confira-os individualmente; Observe que as strings válidas, como "That's not a bug!" , serão sinalizadas. Se isso não destacar o problema, tente novamente com '"\n' (para encontrar aspas duplas não correspondentes). Em seguida, expanda o tr para permitir () , {} e, finalmente, {} para passar. Neste ponto, a inspeção manual da produção se torna uma busca menos proveitosa; enquanto ( e ) são geralmente correspondidos na mesma linha, e citações e colchetes quase sempre são, isso não é verdade de { e } .

Se você reduziu o problema a uma incompatibilidade de chaves, e, especialmente, se você restringiu um intervalo no arquivo, vá para o Plano B. Abra o arquivo em vim (ou vi ). Vá para um caractere { que você acredita ser antes do erro e digite % . Se o cursor pular para o } que você acha que corresponde ao { que você começou, avance para o próximo { e repita. Se ele pular para um } que não corresponde ao { iniciado, o erro ocorre entre essas duas chaves. Se não se move, o erro ocorre entre a sua localização atual e o final do arquivo. Zoom in.

Essa abordagem pode ser um pouco mais adequada para arquivos de programa em linguagens como C, C ++ e Java (se seus compiladores não fizerem um bom trabalho), mas deve funcionar muito bem para scripts de shell.

    
por 25.05.2015 / 04:35
5

O caminho mais fácil? Use um editor com coloração de sintaxe que esteja ciente do shell que você está usando e inspecione visualmente. Quando você obtém uma grande faixa de cor das cordas, sabe que deixou de fora uma citação. Apenas sobre qualquer editor de programação decente tem coloração de sintaxe.

A coloração de sintaxe às vezes dá errado, mas geralmente é um sinal de que seu programa é muito complexo e os humanos provavelmente também errarão.

Para programação de shell, certifique-se de usar uma fonte em que " , ' e ' sejam fáceis de diferenciar. Verifique se você não usou inadvertidamente caracteres não-ASCII que se parecem com aspas ASCII, como ‘’“” .

    
por 25.05.2015 / 00:54
4

Uma ferramenta de lintagem externa como o ShellCheck pode detectar problemas e pode ter mensagens e locais melhores do que bash em si.

Para um programa que é na maior parte instruções echo com um "${MY_ARRAY[1]" no meio, o ShellCheck informa que não foi possível analisar a string entre aspas. Ele até reduz o problema para o caractere $ e sugere que a expansão do parâmetro estava com defeito.

O ShellCheck funciona com o Vim, o Emacs, o SublimeText e o Atom (entre outros).

    
por 25.05.2015 / 07:42
1

Consegui resolver um grande problema que tive em um script bash de 2000+ linhas usando a solução de baixa tecnologia da G-Man.

Acabei de adicionar a seguinte linha, que faz o mesmo para o número ímpar de duplas que a resposta do G-Man para aspas simples.

tr -cd "\"\n" < my_script.sh | awk 'length%2==1 {print NR, $0}'

Btw, o shellcheck.net é muito legal e todo bom script deve passar por isso.

    
por 23.09.2015 / 16:57