удаленная команда SSH работает, но не при использовании в сценарии bash

Я пытаюсь остановить tomcat на удаленном сервере с помощью сценария bash. Вот функция:

function stop_remote_tomcat () {
    CURRENT_SERVER=$1
    CURRENT_USER=$2
    CURRENT_PEM_FILE=$3

    COMMAND="ssh -i $CURRENT_PEM_FILE $CURRENT_USER@$CURRENT_SERVER \"/bin/sh sudo /etc/init.d/tomcat stop\""
    echo $COMMAND
    $COMMAND
}

Затем внутри оператора case вызывается эта функция.

Моя проблема в том, что если я просто копирую вывод оператора echo $ COMMAND и запускаю его как независимую команду, он отлично работает. Но когда он запускается в сценарии, он выдает ошибку:

sudo /etc/init.d/tomcat stop: No such file or directory

Кто-нибудь может объяснить, как этого можно достичь в сценарии bash?

0
задан 1 March 2016 в 21:51
1 ответ

Краткий ответ: см. BashFAQ # 50: Я пытаюсь поместить команду в переменную, но сложные случаи всегда терпят неудачу! .

Длинный ответ: Помещение команд в переменные работает неправильно из-за порядка, в котором оболочка анализирует вещи. В частности, он анализирует кавычки, экранирование и т. Д., Прежде чем расширять переменные, поэтому встраивание кавычек в переменные не работает - к тому времени, когда они находятся в командной строке, им уже слишком поздно делать что-нибудь полезное. Можно было бы сохранить команду в массиве вместо простой переменной, а затем использовать printf% q для цитирования любых частей, которые нуждаются в ней для печати:

[...]
COMMAND=(ssh -i $CURRENT_PEM_FILE $CURRENT_USER@$CURRENT_SERVER "/bin/sh sudo /etc/init.d/tomcat stop")
printf "%q " "${COMMAND[@]}"
echo    # Because printf won't add a linefeed
"${COMMAND[@]}"

Проблема в том, что она существует много способов заключить переменную в кавычки / избежать пробелов, и % q может не выбрать тот, который вам нравится. Другой вариант - пропустить сохранение команды и просто распечатать ее «вручную»:

[...]
echo "ssh -i $CURRENT_PEM_FILE $CURRENT_USER@$CURRENT_SERVER \"/bin/sh sudo /etc/init.d/tomcat stop\""
ssh -i $CURRENT_PEM_FILE $CURRENT_USER@$CURRENT_SERVER "/bin/sh sudo /etc/init.d/tomcat stop"
0
ответ дан 5 December 2019 в 10:40

Теги

Похожие вопросы