O operador $(...)
, chamado substituição do comando , é aquele que se expande para a saída padrão de um comando livre de seus caracteres de nova linha.
Quando não está em lista e em contextos de lista, também está sujeito a split + glob ( split apenas em zsh
).
Por exemplo, se cmd
outputs *:x\n\n
e $IFS
contiver :
, $(cmd)
expandiria para *:x
e, no contexto da lista, seria dividido em *
e x
e *
seria expandido para a lista de arquivos no diretório atual.
Então, normalmente:
cmd1 $(cmd2)
com o valor padrão de $IFS
(espaço, tabulação e nova linha) destina-se a passar para cmd1
a lista de arquivos que correspondem à lista de padrões (espaço / guia / nova linha delimitada) gerados por cmd2
.
Aqui, dada a mensagem de erro emitida pelo cmd1
, parece que o seu cmd2
não produz nada ou apenas espaço, tabulação, caracteres de nova linha que resultam em nenhum argumento foi passado para cmd1
.
Então, você pode precisar cuidar desse caso especial primeiro, como:
set -- $(docker images -f dangling=true -q)
[ "$#" -eq 0 ] || docker rmi "$@"
Ou com o GNU ou FreeBSD xargs
do:
docker images -f dangling=true -q |
xargs -r docker rmi
Isso também evitaria que as palavras produzidas por docker images
fossem tratadas como padrões de arquivo. xargs
espera uma lista delimitada em branco + nova linha de palavras que ela passa como argumento para o comando e também entende algumas formas de citações. Você queria passar um argumento para cada linha de entrada, você usaria (com GNU xargs
):
docker images -f dangling=true -q |
xargs -rd '\n' docker rmi