Estoy trabajando en un script de shell que construye un comando complejo a partir de variables, por ejemplo, de esta manera (con una técnica que aprendí de las preguntas frecuentes de Bash ):
#!/bin/bash
SOME_ARG="abc"
ANOTHER_ARG="def"
some_complex_command \
${SOME_ARG:+--do-something "$SOME_ARG"} \
${ANOTHER_ARG:+--with "$ANOTHER_ARG"}
Esta secuencia de comandos agrega dinámicamente los parámetros --do-something "$SOME_ARG"y --with "$ANOTHER_ARG"de some_complex_commandsi se han definido estas variables. Hasta ahora esto está funcionando bien.
Pero ahora también quiero poder imprimir o registrar el comando cuando lo estoy ejecutando, por ejemplo, cuando mi script se ejecuta en modo de depuración. Entonces, cuando se ejecuta mi script some_complex_command --do-something abc --with def, también quiero tener este comando dentro de una variable para poder, por ejemplo, iniciar sesión en el syslog.
Las preguntas frecuentes de Bash demuestran una técnica para usar la DEBUGtrampa y la $BASH_COMMANDvariable (por ejemplo, con fines de depuración) para este propósito. Lo intenté con el siguiente código:
#!/bin/bash
ARG="test string"
trap 'COMMAND="$BASH_COMMAND"; trap - DEBUG' DEBUG
echo "$ARG"
echo "Command was: ${COMMAND}"
Esto funciona, pero no expande las variables en el comando:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Yo supongo que tengo que usar eval para ampliar echo "$ARG"a echo test string(al menos no he encontrado una manera sin evalembargo). Lo siguiente funciona:
eval echo "Command was: ${COMMAND}"
Produce el siguiente resultado:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Command was: echo test string
Pero no estoy realmente seguro si puedo usarlo de evalmanera segura de esta manera. He intentado explotar sin éxito algunas cosas:
#!/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 manejar esto bien, pero tengo curiosidad si alguien más ve un problema que me he perdido.