3

我有以下命令可以正常工作并foo在返回之前打印:

docker exec -i <id> /bin/sh < echo "echo 'foo'"

我想用一个管道将多个命令定向到容器中,例如echo 'foo'and ls /。我尝试了以下方法:

  1. 这失败了,因为它在主机上运行命令并将输出通过管道传输到容器中:
    {
        echo "foo"
        ls /
    } | docker exec -i <id> /bin/sh
    
  2. 这失败了,因为它的语法不好。它也在主机上运行:

    {
        echo "foo"
        ls /
    } | docker exec -i <id> /bin/sh
    
  3. 这个失败了,但我不想使用字符串数组:

    for COMMAND in 'echo "foo"' 'ls /'
    do
        docker exec -i <id> /bin/sh < echo $COMMAND
    done
    

我还尝试了其他几种方法,例如将命令输入teeorecho但没有任何运气。如果你想知道我为什么要做这件看似荒谬的事情,那是因为:

  • 这是一个简短的脚本,我想将所有内容放在一个地方
  • 我想使用语法突出显示,所以我不想将它全部存储在字符串列表中
  • 容器有脚本应该运行的程序,而主机没有
  • 这是一个自动过程,我想在主机上使用 crontab 触发
4

3 回答 3

4

您可以按以下方式运行一组命令

 docker exec -i <id> /bin/sh -c 'echo "foo"; ls -l'

或者

docker exec -i 996eee5d121d /bin/sh -c 'echo 'foo'; ls -l'

或者

docker exec -i 996eee5d121d /bin/sh -c 'echo foo; ls -l'

如果要运行 2 个以上的命令,只需;在每个命令之后附加,例如

docker exec -i 996eee5d121d /bin/sh -c 'echo "foo"; ls -l; ls -a'
于 2020-06-04T00:29:32.980 回答
1

使用此处的文档。

docker run -i --rm alpine /bin/sh <<EOF
echo abc
ls /
EOF

请注意此处引用和未引用的文档分隔符之间的区别。

docker exec -i <id> /bin/sh < echo "echo 'foo'"

我认为你的意思是:

docker exec -i <id> /bin/sh < <(echo "echo 'foo'")

这与以下内容相同:

docker exec -i <id> /bin/sh <<<"echo 'foo'"

@edit 有一个很酷的小技巧。这个想法是将除了第一行之外的脚本本身通过管道传输到另一个子进程,它有时被安装程序脚本使用:

#!/bin/sh
# output this script except first 4 lines to docker
tail -n+5 "$0" | docker run -i --rm alpine /bin/sh -x
exit  # we exit original script
#!/bin/sh
# inside docker now
echo abc
ls /

执行:

$ bash -x ./script.sh
+ tail -n+5 ./script.sh
+ docker run -i --rm alpine /bin/sh -x
+ echo abc
+ ls /
abc
bin
...
var
+ exit

例如,您可以以类似的方式使用sed或其他解析工具来提取某些标记之间的唯一相关部分。

于 2020-06-04T16:28:39.180 回答
0

我找到了一个要点,它解释了如何将命令输入docker exec

echo "echo foo" | docker exec -i <id> /bin/sh -

现在我们需要一种管道多个命令的方法。命令组不起作用,因为它们在主机上运行,​​而分号分隔的命令可能会变得混乱。我想写一个函数并得到它的主体,事实证明你可以用一个简单的declaresed调用来做到这一点。

您可以组合所有这些部分以将命令通过管道传输到容器中:

function func {
    echo "foo"
    ls /
}

declare -f func | sed '1,2d;$d' | docker exec -i <id> /bin/bash -

语法高亮在函数中仍然有效,并且易于阅读。

如果要使用容器中主机上的环境变量,则必须在 docker exec 中手动列出它们,如下所示:

... | docker exec -i -e VAR=$VAR <id> /bin/bash -

编辑:我把它留在这里作为一个可能的解决方案,但接受的答案是我正在使用的正确解决方案。

于 2020-06-04T15:58:19.643 回答