0

I have a requirement to execute some commands on remote machine and i have written script like this on my local machine.

Basically i'm getting docker images on my local machine and want to check whether those images are existing in remote server or not.

I need to get non existing docker images (remote server) to my local machine. For that i have used below mentioned code, but it didn't work for me.

#!/bin/sh
declare array=$(docker images)
sshpass -p 'password' ssh -t username@1.2.3.4 << EOF
declare List=""
while read -r line; do
  if [ -z $(docker images -q $line) ]; then
    List="$List $line"
  else
    continue
  fi
done <<< "$array"
EOF

I want List variable to be in my local machine.

Can anyone help me on this issue?
Your help is much appreciated.
Best Regards.

Jainish Kapadia
  • 2,603
  • 5
  • 18
  • 29
kala
  • 63
  • 2
  • 13

2 Answers2

1

Nothing you do in the remote shell will be present in your local shell once the remote shell exits. What you can do is have the remote shell print output and capture that.

By the by, you can't use arrays in a /bin/sh script, but we don't actually need arrays here.

#!/bin/sh
docker images |
sshpass -p 'password' ssh -t username@1.2.3.4 '
  while read -r line; do
    # Suction: docker images -q image should return nonzero exit status
    # if the named image is missing.  We work around that by grepping
    # for whether there is any output at all.
    docker images -q "$line" | grep -q . || echo "$line"
  done'

This just prints out the result; capture that into a variable or redirect it to a file in order to do something more with it, or just pipe it into another local while read -r loop.

If you refactor this so that e.g. the authentication details are parametrized, you can run it against a number of hosts. You could save it as an executable script so you can call it from any other tool, or as a function if you just need it in a limited context.

missing () {
    docker images -q |
    "$@" 'while read -r line; do          
        docker images -q "$line" | grep -q . || echo "$line"
    done'
}

Now you can call it for one or more hosts:

missing sshpass -p 'password' ssh -t username@1.2.3.4 |
xargs -r -n 1 docker pull
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • http://stackoverflow.com/questions/5725296/difference-between-sh-and-bash discusses the differences between `sh` and `bash`. – tripleee Feb 07 '17 at 09:47
  • Parametrizing the entire ssh command line is perhaps a somewhat dubious design, but at least it should inspire you to explore how this can be made modular and reusable. – tripleee Feb 07 '17 at 10:04
  • its working really fine. but i am executing this script in jenkins which says sshapss command not found and we are not supposed to install anything. Is there anyway to use ssh command with password like ssh -p 'password' -u 'username' – kala Feb 07 '17 at 12:16
  • The traditional solution to that is public keys. – tripleee Feb 07 '17 at 12:23
  • how can i get value in line to my local server – kala Feb 07 '17 at 12:23
  • `ssh remote echo moo` produces the output on standard output, from where you can redirect it or store it in a local file. For example, `value=$(ssh remote echo moo)` is a really poor way to paraphrase `value=moo` with a remote shell. – tripleee Feb 07 '17 at 12:24
0

Depending on your requirements, you could also make the docker socket remotely available: https://docs.docker.com/engine/reference/commandline/dockerd/#/daemon-socket-option

Than, you could rewrite your script in such a way, that it connects to the local/remote docker engine:

DOCKER_HOST=unix:///var/run/docker.sock/ docker images ...
DOCKER_HOST=tcp://remote.ip:2375 docker images ...

I know that is not what you asked for, but maybe it inspires others.

Martin
  • 2,754
  • 1
  • 15
  • 35