DenCowboy
DenCowboy

Reputation: 15106

Execute for loop in docker container

I use a docker container to perform a curl

docker run --rm --network=mynetwork tutum/curl for i in `seq 1 10`; do curl -s http://Url; done

But the output is -bash: syntax error near unexpected tokendo'`. How do I execute this in a proper way. I want to see the output without going inside the container or checking their logs.

For example this works:

docker run --rm -d -it --network=mynetwork tutum/curl /bin/sh
docker exec -it 4e8cb1e8c9fb bash
root@4e8cb1e8c9fb:/# for i in `seq 1 20`; do curl http://Url; done
curl: (6) Could not resolve host: url
curl: (6) Could not resolve host: url
curl: (6) Could not resolve host: url
curl: (6) Could not resolve host: url
curl: (6) Could not resolve host: url
curl: (6) Could not resolve host: url
...

Upvotes: 7

Views: 17807

Answers (3)

BMitch
BMitch

Reputation: 264156

As Aaron points to, you need a shell inside the container to parse this line, rather than letting it get parsed by the same shell that parses the docker command. By default docker will pass commands to a /bin/sh entrypoint if you don't have one defined. And if you try escaping any shell characters on the docker cli, it "helps" you by also escaping them on the /bin/sh command line which prevents you from passing something like a ; through and getting it parsed by the shell there or quoting your script and having it parsed by the /bin/sh -c. If you quote the script without parsing it, you'll find that it looks for an executable with the full string's name.

The solution, as you've found, is to run a shell with /bin/sh -c "your script" as your command. Note that the script you run needs to be a single argument to /bin/sh -c, anything else will get passed as args to that script (which you can read with $0, $1, etc).

The resulting command should look like:

docker run --rm --network=mynetwork tutum/curl \
  /bin/sh -c 'for i in `seq 1 10`; do curl -s http://Url; done'

Upvotes: 7

Aaron
Aaron

Reputation: 24802

Your problem happens because the ; after your for is parsed by the bash outside your container as a command separator, so these are the two commands you're executing :

  1. docker run --rm --network=mynetwork tutum/curl for i in `seq 1 10`
  2. do curl -s http://Url; done

The second is invalid, which is what the error you're getting means.

I think you could simply enclose the command you want to pass to docker in single-quotes :

docker run --rm --network=mynetwork tutum/curl 'for i in $(seq 1 10); do curl -s http://Url; done'

The use of single-quotes over double-quotes means that the command won't be expanded in your current shell but rather inside the docker component. It doesn't matter here as the only thing to expand is the seq 1 10 subshell which will obviously produce the same result on both environments.

Upvotes: 3

GreensterRox
GreensterRox

Reputation: 7150

Maybe try wrapping docker call in a bash script and loop?

#!/bin/bash
for i in {1..20}
do
   docker run -i -t --entrypoint curl http://Url;
done

Upvotes: -1

Related Questions