如何将命令正确发送到 docker 容器中?

How to send a command properly into docker container?

我可以在我的终端中成功执行下面的命令。
命令:

gdalwarp -s_srs "+datum=WGS84 +no_defs +geoidgrids=egm96-15.gtx" -t_srs "+datum=WGS84 +no_def" input.tif output.tif

现在,我想将此命令存储到一个变量中并在 docker 容器中展开此命令。

我的脚本 run.sh 如下所示。我首先将我的目标命令存储到 mycommand 和 运行 容器中,并将命令作为输入。

mycommand=$@;
docker run -ti --rm osgeo/gdal:ubuntu-small-latest /bin/bash -c "cd $(pwd); ${mycommand}"

然后我执行 run.sh 如下。

bash run.sh gdalwarp -s_srs "+datum=WGS84 +no_defs +geoidgrids=egm96-15.gtx" -t_srs "+datum=WGS84 +no_def" input.tif output.tif

问题:

  1. 我希望 bash run.sh 之后的所有内容都可以按字面意义存储到 mycommand 变量中。
  2. 而在docker容器内,mycommand可以按字面意思展开执行。但是貌似我原命令中的双引号会在这个过程中丢失。

谢谢。

您可以将命令作为参数传递,然后在 shell 中调用 "$@"。我更喜欢单引号。

docker run -ti --rm osgeo/gdal:ubuntu-small-latest \
    /bin/bash -c 'cd '"$(pwd)"' && "$@"' -- "$@"

如果您只需要 cd,只需让 docker 使用 -w 更改目录。在 Bash $PWD 中会比 pwd 命令更快。

docker run ... -w "$PWD" image "$@"

请注意 "$(pwd)" 在 child shell 中没有正确引用 - 结果将进行分词和文件名扩展。无论如何,我推荐 declare -p 和 Bash 数组(以及 declare -f 函数)在 Bash-es 之间传输数据。 declare 将始终正确引用所有内容,以便 child shell 可以正确导入它。

cmd=("$@")
pwd=$PWD
work() {
   cd "$pwd"
   "${cmd[@]}"
}
docker ... bash -c "$(declare -p pwd cmd); $(declare -f work); work"

研究:何时在 shell 中使用引号、单引号和双引号的区别、分词 扩展以及如何防止它,https://mywiki.wooledge.org/Quotes , bash arrays, https://mywiki.wooledge.org/BashFAQ/050