我有一个非常简单的 shell 脚本,应该删除浮动的 docker 图像,命令是:docker rmi $(docker images -f "dangling=true" -q)
现在我遇到了一个问题,我认为是由$
.但我可能是错的。
我的脚本是这样的:
#!/bin/bash
cd /Users/jared/Projects
for d in ./*/ ;
do (cd "$d" && docker rmi $(docker images -f "dangling=true" -q); true); done
当我运行它时,它会打印到屏幕上:
“docker rmi”需要至少 1 个参数。
请参阅“docker rmi --help”。
用法:docker rmi [选项] IMAGE [IMAGE...]
删除一张或多张图像
我做出的假设是因为这个$(docker imag...)
角色,当然$
是一个特殊的角色。
我该如何逃脱或者至少让我的脚本按照我想要的方式运行?
答案1
运营$(...)
商称为命令替换,是扩展为删除其尾随换行符的命令的标准输出的输出。
当不加引号并且在列表上下文中时,它也受到 split+glob (分裂只有在zsh
)。
例如,如果cmd
输出*:x\n\n
和$IFS
contains :
,$(cmd)
将扩展为*:x
和 在列表上下文中,它将拆分为*
和x
,并将*
扩展为当前目录中的文件列表。
所以通常:
cmd1 $(cmd2)
默认值为$IFS
(空格、制表符和换行符)意味着传递到与 .cmd1
输出的(空格/制表符/换行符分隔)模式列表匹配的文件列表cmd2
。
在这里,给出您的错误消息输出cmd1
,看起来像你的cmd2
不输出任何内容或仅输出空格、制表符、换行符,这会导致没有参数传递给cmd1
.
因此,您可能需要首先处理这种特殊情况,例如:
set -- $(docker images -f dangling=true -q)
[ "$#" -eq 0 ] || docker rmi "$@"
或者使用 GNU 或 FreeBSDxargs
执行以下操作:
docker images -f dangling=true -q |
xargs -r docker rmi
这也将避免输出的单词被docker images
视为文件模式。xargs
需要一个空白+换行符分隔的单词列表,它作为参数传递给命令,并且还理解某些形式的引用。如果您想为每一行输入传递一个参数,您可以使用(使用 GNU xargs
):
docker images -f dangling=true -q |
xargs -rd '\n' docker rmi