Pracuję nad skryptem powłoki, który konstruuje złożone polecenie ze zmiennych, np. Takich jak ten (z techniką, której nauczyłem się z Bash FAQ ):
#!/bin/bash
SOME_ARG="abc"
ANOTHER_ARG="def"
some_complex_command \
${SOME_ARG:+--do-something "$SOME_ARG"} \
${ANOTHER_ARG:+--with "$ANOTHER_ARG"}
Ten skrypt dynamicznie dodaje parametry --do-something "$SOME_ARG"i --with "$ANOTHER_ARG"aby some_complex_command, jeśli te zmienne są zdefiniowane. Jak dotąd działa to dobrze.
Ale teraz chcę też móc wydrukować lub zalogować polecenie, gdy je uruchamiam, na przykład gdy mój skrypt jest uruchomiony w trybie debugowania. Więc kiedy mój skrypt działa some_complex_command --do-something abc --with def, chcę również mieć to polecenie w zmiennej, aby np. Móc zalogować się do syslog.
Bash FAQ pokazuje technikę wykorzystania DEBUGpułapki i $BASH_COMMANDzmiennej (na przykład do celów debugowania) w tym celu. Próbowałem tego z następującym kodem:
#!/bin/bash
ARG="test string"
trap 'COMMAND="$BASH_COMMAND"; trap - DEBUG' DEBUG
echo "$ARG"
echo "Command was: ${COMMAND}"
To działa, ale nie rozwija zmiennych w poleceniu:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Myślę, że muszę użyć eval, by rozwinąć się echo "$ARG"do echo test string(przynajmniej nie znalazłem sposobu bez którego eval). Działa to:
eval echo "Command was: ${COMMAND}"
Daje następujące dane wyjściowe:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Command was: echo test string
Ale nie jestem pewien, czy mogę evalbezpiecznie używać tego w ten sposób. Bezskutecznie próbowałem wykorzystać niektóre rzeczy:
#!/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}"
Wygląda na to, że dobrze sobie z tym radzi, ale jestem ciekawy, czy ktoś widzi problem, który mi umknął.