ctsh: a tool for running commands on Docker containers

ctsh: a tool for running commands on Docker containers

So I'm doing a fair amount of testing of container configurations. To do this, I tweak the Dockerfile, build the image, and then run some commands in the container to test my configuration. One thing that has always been a little annoying is having to find the name of the container if I didn't explictly give it an alias. I could certainly do that, but what if I just randomly spin up a container?

I decided to write a little command called ctsh that would basically let me run a command on a container by specifying a search query and an optional command to run (defaults to bash). The script then looks up the container id by matching the search query against the container id (so you can specify just part of the container id), the image name, or the name that docker assigned to it. Most of the time, you are running just one container with a particular image, so it should match right away. The script will then echo the docker command that it actually runs:


$ docker ps | awk '{print $1, " ", $2}' | grep jboss
188d80ecd617   jboss/wildfly

$ ctsh jboss
/usr/bin/docker exec -it 188d80ecd617 bash
[jboss@188d80ecd617 ~]$

In some cases, however, you might have more than one container running with the same image. In this case, the script will prompt you for which container you want:


$ ctsh nginx
serveral matches:

0: 2713ea7702f0        nginx               "nginx -g 'daemon of…"   8 minutes ago       Up 8 minutes        80/tcp              quizzical_jones
1: 5baaed03e20b        nginx               "nginx -g 'daemon of…"   8 minutes ago       Up 8 minutes        80/tcp              thirsty_hermann
2: 51e3ece9f2aa        nginx               "nginx -g 'daemon of…"   8 minutes ago       Up 8 minutes        80/tcp              silly_bardeen
3: e429c99e2be7        nginx               "nginx -g 'daemon of…"   5 hours ago         Up 5 hours          80/tcp              zealous_goldstine
4: fdcef29b6d64        nginx               "nginx -g 'daemon of…"   5 hours ago         Up 5 hours          80/tcp              pensive_yonath
Enter # from choices above (or 'exit' to quit) >> 3
/usr/bin/docker exec -it e429c99e2be7 bash
root@e429c99e2be7:/#

You can specify additional arguments that are a command to run. The additional arguments are appended to the docker exec command:


$ ctsh jboss df -h
/usr/bin/docker exec -it 188d80ecd617 df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          78G  5.1G   73G   7% /
tmpfs            64M     0   64M   0% /dev
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/vda1        78G  5.1G   73G   7% /etc/hosts
shm              64M     0   64M   0% /dev/shm
tmpfs           2.0G     0  2.0G   0% /proc/scsi
tmpfs           2.0G     0  2.0G   0% /sys/firmware

If you want to run a command involving a variable (a variable defined inside the container), you will need to use a special syntax:


$ ctsh jboss sh -c "'echo \$PATH'"
/usr/bin/docker exec -it 188d80ecd617 sh -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Essentially, you are executing the sh command with a -c argument that is the command to run inside the sh command. The argument following that is double quoted and then single quoted inside that so that the stuff inside the single quotes is passed as a single argument to docker exec. You also have to escape the dollar sign so that the variable isn't interpreted in the local host.

You can find the script here:

https://github.com/openshiftninja/dockertools/blob/master/scripts/ctsh

If you find this command helpful, or you have ideas for improving this script, please leave a comment below!

Related Article