Sto lavorando a uno script di shell che costruisce un comando complesso da variabili, ad esempio in questo modo (con una tecnica che ho imparato dalle FAQ di Bash ):
#!/bin/bash
SOME_ARG="abc"
ANOTHER_ARG="def"
some_complex_command \
${SOME_ARG:+--do-something "$SOME_ARG"} \
${ANOTHER_ARG:+--with "$ANOTHER_ARG"}
Questo script aggiunge in modo dinamico i parametri --do-something "$SOME_ARG"e --with "$ANOTHER_ARG"per some_complex_commandse vengono definite queste variabili. Finora funziona bene.
Ma ora voglio anche essere in grado di stampare o registrare il comando quando lo eseguo, ad esempio quando il mio script viene eseguito in modalità debug. Quindi, quando il mio script viene eseguito some_complex_command --do-something abc --with def, voglio anche avere questo comando all'interno di una variabile in modo da poterlo ad esempio accedere al syslog.
Le FAQ di Bash mostrano una tecnica per utilizzare la DEBUGtrap e la $BASH_COMMANDvariabile (ad esempio per scopi di debug) a questo scopo. L'ho provato con il seguente codice:
#!/bin/bash
ARG="test string"
trap 'COMMAND="$BASH_COMMAND"; trap - DEBUG' DEBUG
echo "$ARG"
echo "Command was: ${COMMAND}"
Funziona, ma non espande le variabili nel comando:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Credo che devo usare eval per espandere echo "$ARG"a echo test string(almeno io non ho trovato un modo senza evalancora). Il seguente funziona:
eval echo "Command was: ${COMMAND}"
Produce il seguente output:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Command was: echo test string
Ma non sono davvero sicuro di poter usare in evalsicurezza in questo modo. Ho tentato senza successo di sfruttare alcune cose:
#!/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}"
Sembra gestirlo bene, ma sono curioso di sapere se qualcun altro vede un problema che mi è sfuggito.