Я работаю над сценарием оболочки, который создает сложную команду из переменных, например, вот так (с техникой, которую я изучил из Bash FAQ ):
#!/bin/bash
SOME_ARG="abc"
ANOTHER_ARG="def"
some_complex_command \
${SOME_ARG:+--do-something "$SOME_ARG"} \
${ANOTHER_ARG:+--with "$ANOTHER_ARG"}
Этот скрипт динамически добавляет параметры --do-something "$SOME_ARG"и --with "$ANOTHER_ARG"в some_complex_commandслучае определены эти переменные. Пока это работает нормально.
Но теперь я также хочу иметь возможность печатать или регистрировать команду, когда я ее запускаю, например, когда мой скрипт выполняется в режиме отладки. Поэтому, когда мой скрипт выполняется some_complex_command --do-something abc --with def, я также хочу, чтобы эта команда была внутри переменной, чтобы я мог, например, записать ее в системный журнал.
Bash FAQ демонстрирует методику использования DEBUGловушки и $BASH_COMMANDпеременной (например, в целях отладки) для этой цели. Я пробовал это с помощью следующего кода:
#!/bin/bash
ARG="test string"
trap 'COMMAND="$BASH_COMMAND"; trap - DEBUG' DEBUG
echo "$ARG"
echo "Command was: ${COMMAND}"
Это работает, но не раскрывает переменные в команде:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Я предполагаю , что я должен использовать Eval для расширения , echo "$ARG"чтобы echo test string(по крайней мере , я не нашел способ , не все evalже). Следующее работает:
eval echo "Command was: ${COMMAND}"
Он производит следующий вывод:
host ~ # ./test.sh
test string
Command was: echo "$ARG"
Command was: echo test string
Но я не совсем уверен, смогу ли я использовать evalбезопасно, как это. Я безуспешно пытался использовать некоторые вещи:
#!/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}"
Кажется, с этим хорошо справляются, но мне любопытно, если кто-то еще увидит проблему, которую я пропустил.