Estou trabalhando em um script de shell que constrói um comando complexo a partir de variáveis, por exemplo, assim (com uma técnica que aprendi nas Perguntas frequentes do Bash ):
#!/bin/bash
SOME_ARG="abc"
ANOTHER_ARG="def"
some_complex_command \
${SOME_ARG:+--do-something "$SOME_ARG"} \
${ANOTHER_ARG:+--with "$ANOTHER_ARG"}
Este script adiciona dinamicamente os parâmetros --do-something "$SOME_ARG"e --with "$ANOTHER_ARG"para some_complex_commandse estas variáveis são definidas. Até agora, isso está funcionando bem.
Mas agora também quero poder imprimir ou registrar o comando enquanto o estiver executando, por exemplo, quando meu script for executado no modo de depuração. Portanto, quando meu script é executado some_complex_command --do-something abc --with def, eu também quero ter esse comando dentro de uma variável para poder, por exemplo, registrá-lo no syslog.
As Perguntas frequentes sobre o Bash demonstram uma técnica para usar a DEBUGinterceptação e a $BASH_COMMANDvariável (por exemplo, para fins de depuração) para esse fim. Eu tentei isso com o seguinte código:
#!/bin/bash
ARG="test string"
trap 'COMMAND="$BASH_COMMAND"; trap - DEBUG' DEBUG
echo "$ARG"
echo "Command was: ${COMMAND}"
Isso funciona, mas não expande as variáveis no comando:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Eu acho que eu tenho que usar eval para expandir echo "$ARG"a echo test string(pelo menos eu não encontrei uma maneira sem evalainda). O seguinte funciona:
eval echo "Command was: ${COMMAND}"
Produz a seguinte saída:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Command was: echo test string
Mas não tenho certeza se posso usar evalcom segurança assim. Tentei, sem sucesso, explorar algumas coisas:
#!/bin/bash
ARG="test string; touch /x"
DANGER='$(touch /y; cat /etc/shadow)'
trap 'COMMAND="$BASH_COMMAND"; trap - DEBUG' DEBUG
echo "$ARG" $DANGER
echo "Command was: ${COMMAND}"
eval echo "Command was: ${COMMAND}"
Parece lidar bem com isso, mas estou curioso para saber se alguém viu um problema que eu perdi.