在Docker容器中执行for循环

7
我使用一个Docker容器来执行Curl。
docker run --rm --network=mynetwork tutum/curl for i in `seq 1 10`; do curl -s http://Url; done

但是输出是-bash: syntax error near unexpected token do'。我该如何正确执行它?我想查看输出,而不必进入容器或检查其日志。

例如,这样可以正常工作:

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
...
3个回答

7
正如Aaron指出的那样,您需要在容器内部使用shell解析此行,而不是让它由解析docker命令的相同shell解析。默认情况下,如果您没有定义入口点,docker将命令传递给/bin/sh。如果您尝试在docker cli上转义任何shell字符,则它会通过在/bin/sh命令行上也对它们进行转义来“帮助”您,这会防止您通过并使其由那里的shell解析,或者引用您的脚本并使其由/bin/sh -c解析。如果您引用脚本而不解析它,则会发现它会查找具有完整字符串名称的可执行文件。
正如您发现的那样,解决方案是使用/bin/sh -c "your script"运行shell作为您的命令。请注意,您运行的脚本需要是/bin/sh -c的单个参数,否则将将任何其他内容作为参数传递给该脚本(您可以使用$0$1等读取这些参数)。
得到的命令应该像这样:
docker run --rm --network=mynetwork tutum/curl \
  /bin/sh -c 'for i in `seq 1 10`; do curl -s http://Url; done'

3
你的问题是因为在你的 for 后面的 ; 被 bash 解析为命令分隔符,所以你正在执行这两个命令:
  1. docker run --rm --network=mynetwork tutum/curl for i in `seq 1 10`
  2. do curl -s http://Url; done
第二个是无效的,这就是你收到的错误的意思。
我认为你可以简单地用单引号括起来要传递给 docker 的命令。
docker run --rm --network=mynetwork tutum/curl 'for i in $(seq 1 10); do curl -s http://Url; done'

单引号与双引号的使用意味着命令不会在当前 shell 中展开,而是在 docker 组件中展开。这里无关紧要,因为唯一需要展开的是 seq 1 10 子 shell,在两个环境中显然会产生相同的结果。

谢谢,但现在我得到了类似于“done": 在$PATH中找不到可执行文件”(带有单引号)的东西。如果没有单引号并使用您的$(),那么它只是与以前相同的错误。 - DenCowboy
@DenCowboy $()和反引号具有相同的效果,我只是转换到更现代的$(),因为它有一些优点,例如嵌套的可能性,但在您的情况下这并不重要。你能否编辑你问题中的确切错误信息?现在看起来像是在done关键字后面多了一个双引号,导致它被误解,但我不知道是什么原因导致了这个问题。 - Aaron
"...tutum/curl /bin/bash -c 'for i..." 这个可行。如果你想的话可以进行编辑。是通过你的回答找到的,非常感谢。 - DenCowboy
嗯,如果不理解为什么有效,我宁愿不编辑我的答案。我会尝试理解这里发生了什么,但如果几个小时内我没有编辑,你可以点赞我的答案,发布你自己的答案并接受它。 - Aaron
看起来 docker run 使用 /bin/sh -c 来执行它提供的命令,所以要么你在第一次尝试时打错了字,要么是有其他东西添加了额外的 ",你的 URL 包含引号,或者该命令在 bash 中有效但在 sh 中无效。此外,/bin/sh -c 'for i in seq 1 10; do echo $i;done' 可以正常工作,所以我怀疑最后一个原因。 - Aaron

0
也许尝试将docker调用包装在一个bash脚本中并循环执行?
#!/bin/bash
for i in {1..20}
do
   docker run -i -t --entrypoint curl http://Url;
done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接