Pouco antes do shell do shell, eu respondi a uma pergunta no StackOverflow sobre a eliminação de comentários em scripts do bash. Minha resposta usou o truque simples de criar uma função colocando o conteúdo do arquivo de script dentro de tmp_() { ... }
e, em seguida, usando declare -f tmp_
para imprimir bem a função. Na saída bem impressa, não há comentários e as linhas continuadas com uma nova linha invertida foram resolvidas para linhas únicas. (Exceto dentro da substituição do comando backticked).
Outra reformatação também é feita. Por exemplo, comandos compostos são divididos em várias linhas. E algumas formas de continuação de linha não são reformatadas; por exemplo, uma linha que termina com um símbolo de pipe não é alterada. Mas deve satisfazer o caso de uso nesta questão. (Veja o exemplo abaixo.)
É claro que a definição da função precisa ser avaliada, o que significa que o script que é bem impresso pode incluir um ataque de injeção. No código sugerido, a definição da função é avaliada por meio do recurso bash, que permite que as funções sejam exportadas e compartilhadas com um processo filho. Na época em que escrevi este pequeno hack, acreditei que o mecanismo era mais seguro do que chamar eval
, mas, no fim das contas, estava errado.
Desde o shellshock, tem havido uma série de aprimoramentos no code bash para importar definições de funções, fechando as portas em pelo menos alguns ataques de injeção, mas claramente não há garantia de que o procedimento é completamente seguro.
Se você for executar o script que está sendo analisado, o uso desse procedimento para uma impressão bonita provavelmente não aumenta sua vulnerabilidade; um invasor poderia simplesmente inserir o código perigoso diretamente no script e não haveria necessidade de passar por obstáculos para ocultar o ataque de uma maneira que pudesse ignorar as verificações de segurança no código de importação da função.
Mesmo assim, você deve pensar cuidadosamente sobre questões de segurança, tanto com este pequeno programa quanto com quaisquer planos que você possa ter para executar scripts arbitrários.
Aqui está a versão do pretty-printer que funciona com um bash pós-shellshock-patched (e não funciona com as versões anteriores do bash):
env "BASH_FUNC_tmp_%%=() {
$(<script_name)
}" bash -c 'declare -f tmp_' | tail -n+2
Substitua o nome do arquivo que contém o script por script_name
na segunda linha. Você pode querer ajustar o comando tail
; ele remove o nome da função do wrapper, mas não remove as chaves que cercam o corpo do script.
A versão original, que funcionará nas versões pré-shell do bash, pode ser encontrada na resposta SO referenciada.
Amostra.
Testado com base na entrada fornecida por Stéphane Chazelas :
{
echo \;
echo a#b;
echo 'foo\
bar';
cat <<EOF
thisis joined
this 'aswell'
$(ls -l)
EOF
cat <<'EOF'
this is\
not joined
EOF
echo "$(ls -l)";
echo 'ls \
-l'
}
Isso difere da saída sugerida por Stéphane:
- As linhas foram recuadas e muitas foram terminadas com ponto e vírgula. Espaços em branco foram adicionados e / ou excluídos em muitas linhas.
-
cat << E\OF
foi alterado paracat <<'EOF'
, que é semanticamente idêntico. - A linha de continuação aninhada na substituição do comando backticked no final não foi modificada. (A linha de continuação na substituição do comando
$(...)
é eliminada.)