0

I have Docker running on an AWS EC2 instance (Elastic Beanstalk). I'd like to interactively run bash in the container automatically with a script I run from my shell without going through typing all the commands every time.

I made this using a superuser answer about printing individual arguments based on regex. If I type or paste it while logged into AWS it runs fine.

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

This is my SSH connect "script":

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

I tried combining the two with no avail using 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"

But no luck. Here's the transcript of console session:

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

myuser@MYCOMPUTER:~$

It seems like it's trying to execute the command and THEN connect? So I swapped it to this:

#!/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

Still the exact same issue. Thanks for help!

2 Answers 2

0

You are correct in your assertion that the subcommand is getting run before the ssh happens. That's because your shell sees the text within $( ... ) and executes it first. It's possible to work around this by enclosing the entire command in single quotes ' instead of double quotes ", but that gets complicated with trying to have nested quotes. Fortunately there's an easier way.

I'm assuming you are wanting to connect to a container which is already running rather than spin up a new container for every new connection. I recommend giving your container a consistent name so you can refer to it when you connect. For example

docker rename dc66a6ad31ca container_shell

Replace dc66a6ad31ca with the name of your running container (which you can get by running docker ps)

Once you do this, run your ssh command like this:

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

and that should do it. The -t option on the ssh command is necessary to force allocation of a pty, then the -t on the docker command does the same inside the container.

It's also possible to do away with sudo in the command if you put your user in the docker group, but that's an optional step.

EDIT

@OrgnlDave pointed out that Elastic Beanstalk doesn't allow one to rename a container, hence the need to grep for it. His solution was to do this:

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

It may also be useful to limit grep's output to just the first match in case there are multiple containers that match the pattern. This can be done by adding -m 1 to the grep command, making the command line look like this:

ssh -i /path/to/my.pem myuser@host -t 'sudo docker exec -it $(sudo docker ps | grep -om1 ecs-awseb-mything-.*) bash'
3
  • Unfortunately Elastic Beanstalk names containers whatever it wants to, so I really have to use a regex or some other pattern matching in order to get the name. I will look into nested single quotes though, thanks
    – OrgnlDave
    Commented Dec 1, 2016 at 21:53
  • Can't figure out where to wrap the command in single-quotes. The whole thing doesn't work, just the $() section doesn't work, changing -t "" to -t'' doesn't work (with properly escaped ' for awk)
    – OrgnlDave
    Commented Dec 1, 2016 at 22:09
  • I used your answer but instead used grep so I could avoid awk's need for single-quotes. here is the answer. If you modify yours to it, I will accept it. 2 days or I'll answer myself :-D ssh -i /path/to/my.pem myuser@host -t 'sudo docker exec -it $(sudo docker ps | grep -o ecs-awseb-mything-.*) bash'
    – OrgnlDave
    Commented Dec 2, 2016 at 6:48
-1

You don't need -t for a tty, just add the remote command without switch.

#!/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" 
1
  • As @virtex pointed out in his answer above this, the $() gets executed first. :-\
    – OrgnlDave
    Commented Dec 1, 2016 at 21:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .