Bash 将命令组直接导入“docker exec”`
我有以下命令,该命令工作正常,并在返回前打印Bash 将命令组直接导入“docker exec”`,bash,docker,docker-exec,Bash,Docker,Docker Exec,我有以下命令,该命令工作正常,并在返回前打印foo: docker exec-i/bin/sh
foo
:
docker exec-i/bin/sh
我想用一个管道将多个命令导入容器,例如echo'foo'
和ls/
。我尝试了以下方法:
{
回声“foo”
ls/
}|码头执行官-i/bin/sh
{
回声“foo”
ls/
}|码头执行官-i/bin/sh
做
docker exec-i/bin/sh
tee
或echo
中,但都没有成功。如果你想知道我为什么要做这件看似荒谬的事,那是因为:
- 这是一个简短的脚本,我想保留在一个地方
- 我想使用语法高亮显示,所以我不想将其全部存储在字符串列表中
- 容器中有脚本应该运行的程序,而主机没有
- 这是一个自动过程,我想在主机上用crontab触发它
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'
我找到了一个解释如何将命令导入docker exec
:
echo“echo foo”| docker exec-i/bin/sh-
现在我们需要一种通过管道传输多个命令的方法。命令组无法工作,因为它们在主机上运行,分号分隔的命令可能会变得混乱。我想写一个函数,然后得到它的主体,结果证明你可以用一个简单的
您可以将所有这些部分组合起来,将命令导入容器:
函数func{
回声“foo”
ls/
}
声明-f func | sed'1,2d$d'| docker exec-i/bin/bash-
语法高亮显示仍然可以在函数中工作,并且易于阅读
如果要使用容器中主机上的环境变量,必须在docker exec中手动列出它们,如下所示:
…|docker exec-i-e VAR=$VAR/bin/bash-
编辑:我将此作为一个可能的解决方案留在这里,但公认的答案是我正在使用的正确解决方案。使用此处文档
docker run -i --rm alpine /bin/sh <<EOF
echo abc
ls /
EOF
执行:
$ 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
或其他解析工具来提取某些标记之间的唯一相关部分。例如,您可以将其写入shell脚本并将其复制到图像中,这样您就不必处理shell转义了吗?更好的方法是,将其设置为独立容器的CMD
。@DavidMaze我不喜欢第一个解决方案,因为我希望能够调整此脚本,而无需重建目标容器。不过,第二种解决方案可能会起作用,它可以通过容器的名称直接连接到容器,而不依赖容器的id。此解决方案失败,但我还是不想使用字符串数组:
请显示什么是“字符串数组”您可能想使用@KamilCuk该示例命令正在字符串数组上循环,并将其分配给命令
变量。数组可能不是正确的术语,但它仍在一个列表上迭代。很抱歉,这对于几个短命令非常有用,但在尝试使用更多命令时变得不可管理,因此建议您使用shell脚本并运行'echo'foo';ls-l'
很奇怪-foo
没有被引用。同样的方式,你可以“echo”“foo”;“ls'-l'
这就是我要找的!语法突出显示在herdoc中不起作用,这很遗憾,但它看起来确实起作用了,而且看起来是解决我的问题的正确方法。当然可以。但是以#
开头的行是注释,所以没有必要删除它们。我删除了我的旧注释。我可以使用sed
获取模式之间的内容,方法如下:sed-n/^#####脚本开始###/,/^###脚本结束###/p“$0”
docker exec -i <id> /bin/sh < <(echo "echo 'foo'")
docker exec -i <id> /bin/sh <<<"echo 'foo'"
#!/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