gpt4 book ai didi

bash - 从另一个命令获取一些环境变量后,在远程主机上运行的 docker 容器中运行任意命令

转载 作者:行者123 更新时间:2023-12-02 20:46:05 25 4
gpt4 key购买 nike

为了展示我正在尝试做的事情,这是我目前拥有的 bash 脚本的一部分:

COMMAND="${@:1}"
CONTAINER_DOCKER_NAME=this-value-is-computed-prior
MY_IP=this-ip-is-computed-prior

ssh user@$MY_IP -t 'bash -c "docker exec -it $( docker ps -a -q -f name='$CONTAINER_DOCKER_NAME' | head -n 1 ) /bin/sh -c "eval $(echo export FOO=$BAR) && $COMMAND""'

所以让我们分解一下长命令:
我正在 ssh-ing 到一个运行 bash 的主机,该 bash 使用 docker ps 获取正确的容器然后我做 docker exec在容器中运行一个 shell 来加载我的 $COMMAND 的一些环境变量需要工作。需要注意的是 $BAR应该是 BAR 的值变量 容器内 .
所以这就是我试图在理论上完成的事情。但是,无论我如何设置大括号、引号或转义字符,在运行它时 - 我总是遇到问题,要么是 shell 语法不正确,要么它没有运行正确的命令(特别是当命令有多个参数时)或者它加载 $BAR来自我的本地桌面或远程主机的值,而不是来自容器的值。

这甚至可以用一个单一的 shell 单衬里吗?

最佳答案

我认为我们可以大大简化您的命令。

首先,没有必要使用eval在这里,你不需要 &&运算符,或者:

/bin/sh -c "eval $(echo export FOO=$BAR) && $COMMAND"

反而:
/bin/sh -c "FOO=$BAR $COMMAND"

设置环境变量 FOO持续时间 $COMMAND .

接下来,你不需要这个复杂的 docker ps表达:
docker ps -a -q -f name="$CONTAINER_DOCKER_NAME"

Docker 容器名称是唯一的。如果您有容器名称
存储在 $CONTAINER_DOCKER_NAME ,你可以运行:
docker exec -it $CONTAINER_DOCKER_NAME ...

这简化了 docker命令下达:
docker exec -it $CONTAINER_DOCKER_NAME \
/bin/sh -c "FOO=\$BAR $COMMAND"

注意我们是如何逃避 $$BAR在那里,因为我们想要那个
在容器内解释,而不是由我们当前的 shell 解释。
现在我们只需要安排通过 ssh 运行它。 .有一对
的解决方案。我们可以确保保护一切
针对额外级别的 shell 扩展的命令行,例如
这:
ssh user@$MY_IP "docker exec -it $CONTAINER_DOCKER_NAME \
/bin/sh -c \"FOO=\\\$BAR $COMMAND\""

我们需要将整个命令用双引号括起来,这意味着我们
需要转义命令中的任何引号(我们不能使用单引号
引号,因为我们实际上想要扩展变量 $CONTAINER_DOCKER_NAME本地)。我们将失去一层 \扩展,所以我们的 \$BAR变成 \\\$BAR .

如果你的命令不是交互式的,你可以减少一点
通过将脚本管道传递给 bash 而不是将其包含在
命令行,像这样:
ssh user@$MY_IP docker exec -i $CONTAINER_DOCKER_NAME /bin/sh <<EOF
FOO=\$BAR $COMMAND
EOF

这简化了获取东西所需的引用和转义
通过容器 shell 。

关于bash - 从另一个命令获取一些环境变量后,在远程主机上运行的 docker 容器中运行任意命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53726415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com