Я думаю, мы можем немного упростить вашу команду.
Во-первых, здесь нет необходимости использовать eval
, и вам не нужен оператор &&
, либо:
/bin/sh -c "eval $(echo export FOO=$BAR) && $COMMAND"
Вместо:
/bin/sh -c "FOO=$BAR $COMMAND"
Задает переменную среды FOO
на время $COMMAND
.
Далее вам не нужен этот комплекс docker ps
выражение:
docker ps -a -q -f name="$CONTAINER_DOCKER_NAME"
Имена контейнеров Docker являются уникальными.Если у вас есть имя контейнера, сохраненное в $CONTAINER_DOCKER_NAME
, вы можете просто запустить:
docker exec -it $CONTAINER_DOCKER_NAME ...
Это упростит команду docker
до:
docker exec -it $CONTAINER_DOCKER_NAME \
/bin/sh -c "FOO=\$BAR $COMMAND"
Обратите внимание, что мыэкранирование $
в $BAR
, потому что мы хотим, чтобы интерпретация внутри контейнера, а не нашей текущей оболочкой.Теперь нам просто нужно организовать это через ssh
.Есть несколько решений для этого.Мы можем просто убедиться, что все в командной строке защищено от дополнительного уровня расширения оболочки, например:
ssh user@$MY_IP "docker exec -it $CONTAINER_DOCKER_NAME \
/bin/sh -c \"FOO=\\\$BAR $COMMAND\""
Нам нужно заключить всю команду в двойные кавычки, что означает, что мы должны избегать любыхкавычки внутри команды (мы не можем использовать одинарные кавычки, потому что мы действительно хотим развернуть переменную $CONTAINER_DOCKER_NAME
локально).Мы потеряем один уровень расширения \
, поэтому наша \$BAR
станет \\\$BAR
.
Если ваша команда не интерактивна, вы можете сделать это немного менее пугающим с помощью конвейера сценария.вместо того, чтобы включать его в командную строку, например:
ssh user@$MY_IP docker exec -i $CONTAINER_DOCKER_NAME /bin/sh <<EOF
FOO=\$BAR $COMMAND
EOF
Это упрощает цитирование и экранирование, необходимые для передачи данных в оболочку контейнера.