【问题标题】:Running a shell command on local files with Docker Alpine使用 Docker Alpine 在本地文件上运行 shell 命令
【发布时间】:2018-07-10 08:44:47
【问题描述】:

我的目录中充满了扩展名为 .dic 的文件,我需要(递归地)重命名它们以获得扩展名为 .dcm。但是,我需要通过运行一个卷安装在本地文件上的 Docker 来做到这一点。

所以,我提取了 Alpine Docker 映像并开始使用它。由于 Alpine 镜像中没有rename 命令,我使用findmvsed

1) 从 Alpine 镜像运行一个容器,将我的本地目录挂载到 /tmp,并在容器中启动一个 shell 会话:

docker run -ti -v `pwd`:/tmp alpine /bin/sh

2) 在容器内,运行重命名命令:

find /tmp -name '*.dic' | while read filename; do mv ${filename} $(echo ${filename} | sed -e 's/\.dic$/\.dcm/'); done

这工作正常,但我真正需要做的是启动容器,运行命令,然后退出。所以我尝试了:

docker run -v `pwd`:/tmp alpine /bin/sh -c "find /tmp -name '*.dic' | while read filename; do mv ${filename} $(echo ${filename} | sed -e 's/\.dic$/\.dcm/'); done"

但它不起作用,文件没有重命名,输出是:

BusyBox v1.28.4 (2018-05-30 10:45:57 UTC) multi-call binary.

Usage: mv [-fin] SOURCE DEST
or: mv [-fin] SOURCE... DIRECTORY

Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY

    -f  Don't prompt before overwriting
    -i  Interactive, prompt before overwrite
    -n  Don't overwrite an existing file

... 对找到的每个要重命名的文件重复一次。

我做错了什么?

【问题讨论】:

    标签: shell docker busybox alpine


    【解决方案1】:

    它不工作的原因是因为使用双引号来包装字符串意味着变量(例如${filename})被插在Alpine shell 外部。您真正想要的是将字符串传递到单引号内的容器中,因此插值发生在容器内。

    以下工作通过使用单引号字符串进行嵌套重命名,其中包含双引号字符串(与问题相反):

    docker run -v pwd:/tmp alpine /bin/sh -c 'find /tmp -name "*.dic" | while read filename; do mv ${filename} $(echo ${filename} | sed -e "s/\.dic$/\.dcm/"); done'
    

    但是,虽然这可行,但它并不是完美的解决方案。在执行的命令中保留使用单引号的另一种方法是将单引号包裹在双引号中并将其粘合到字符串中,例如"'"'s/查找/替换/g'"'"。无数的额外引用和较低的易读性是否值得,这是读者的问题。看起来像这样:

    docker run -v pwd:/tmp alpine /bin/sh -c 'find /tmp -name '"'"'*.dic'"'"' | while read filename; do mv ${filename} $(echo ${filename} | sed -e '"'"'s/\.dic$/\.dcm/'"'"'); done'
    

    TBH 我通常通过将命令放入脚本文件并将其包含在挂载中来解决这种争论,因为那时脚本可以更容易地共享/版本控制。

    【讨论】:

      【解决方案2】:

      遗憾的是 aplpine 没有重命名,加上 docker cli 上的复杂* bash 命令是一种奇怪的动物

      我试了几次......但精神很好:)
      试试这个:

      docker run -v `pwd`:/tmp  alpine /bin/sh -c "find /tmp -name '*.dic' -exec sh -c 'mv $"0" $"{0%.dic}".dcm'  {} \;"
      

      【讨论】:

      • 非常感谢,您的解决方案有效。但我选择了@spikeheap 的答案,因为它让我明白我在使用单引号/双引号时做错了什么。
      • @scandel 没问题,很高兴我能帮上忙
      猜你喜欢
      • 2016-05-28
      • 2020-03-12
      • 2017-09-16
      • 2019-09-02
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多