У меня Docker, работающий на экземпляре AWS EC2 (Elastic Beanstalk). Я хотел бы в интерактивном режиме автоматически запускать bash в контейнере с помощью сценария, который я запускаю из своей оболочки, без необходимости каждый раз вводить все команды.

Я сделал это, используя ответ суперпользователя о печати отдельных аргументов на основе регулярных выражений. Если я ввожу или вставляю его во время входа в AWS, он работает нормально.

sudo docker exec -it $(sudo docker ps | awk '{for(i=1;i<=NF;i++){if($i~/ecs-awseb-mything-.*/){print $i}}}') bash

Это мой SSH коннект "скрипт":

#!/usr/bin/env bash
ssh -i /path/to/my.pem awsuser@myhost

Я попытался объединить два безрезультатно с помощью ssh -t:

#!/usr/bin/env bash
ssh -i /path/to/my.pem awsuser@myhost -t "sudo docker exec -it $(sudo docker ps | awk '{for(i=1;i<=NF;i++){if($i~/ecs-awseb-mything-.*/){print $i}}}') bash"

Но не повезло. Вот расшифровка стенограммы консоли:

myuser@MYCOMPUTER:~$ ./myscript.sh
sudo: unable to resolve host MYCOMPUTER
[sudo] password for myuser:

myuser@MYCOMPUTER:~$

Кажется, что он пытается выполнить команду, а затем подключиться? Так что я поменял его на это:

#!/usr/bin/env bash
ssh -i /path/to/my.pem -t "sudo docker exec -it $(sudo docker ps | awk '{for(i=1;i<=NF;i++){if($i~/ecs-awseb-mything-.*/){print $i}}}') bash" awsuser@myhost

Все та же проблема. Спасибо за помощь!

2 ответа2

0

Вы правы в своем утверждении, что подкоманда запускается до того, как произойдет ssh. Это потому, что ваша оболочка видит текст в $( ... ) и выполняет его первым. Можно обойти эту проблему, заключив всю команду в одинарные кавычки ' вместо двойных кавычек " , но это усложняется попыткой получить вложенные кавычки. К счастью, есть более простой способ.

Я предполагаю, что вы хотите подключиться к уже запущенному контейнеру, а не раскручивать новый контейнер для каждого нового соединения. Я рекомендую дать вашему контейнеру непротиворечивое имя, чтобы вы могли обращаться к нему при подключении. Например

docker rename dc66a6ad31ca container_shell

Замените dc66a6ad31ca на имя вашего работающего контейнера (который вы можете получить, запустив docker ps)

Как только вы сделаете это, запустите команду ssh следующим образом:

ssh -i /path/to/my.pem awsuser@myhost -t "sudo docker exec -it container_shell bash"

и это должно сделать это. Опция -t в команде ssh необходима для принудительного выделения pty, тогда -t в команде docker делает то же самое внутри контейнера.

Также можно покончить с командой sudo, если вы поместите своего пользователя в группу Docker, но это необязательный шаг.

РЕДАКТИРОВАТЬ

@OrgnlDave указал, что Elastic Beanstalk не позволяет переименовывать контейнер, поэтому для него необходимо использовать grep. Его решение было сделать это:

ssh -i /path/to/my.pem myuser@host -t 'sudo docker exec -it $(sudo docker ps | grep -o ecs-awseb-mything-.*) bash'

Также может быть полезно ограничить вывод grep только первым совпадением, если существует несколько контейнеров, которые соответствуют шаблону. Это можно сделать, добавив -m 1 к команде grep, чтобы командная строка выглядела так:

ssh -i /path/to/my.pem myuser@host -t 'sudo docker exec -it $(sudo docker ps | grep -om1 ecs-awseb-mything-.*) bash'
-1

Вам не нужен -t для tty, просто добавьте удаленную команду без ключа.

#!/usr/bin/env bash
ssh -i /path/to/my.pem awsuser@myhost "sudo docker exec -it $(sudo docker ps | awk '{for(i=1;i<=NF;i++){if($i~/ecs-awseb-mything-.*/){print $i}}}') bash" 

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .