'How to correct docker in makefile which requires at least 1 argument for remove all containers command

The docker command "docker container rm $(docker ps -aq) -f" works fine from the command line. However, when I try to run it from a makefile using the following target ("remove_all_containers")...

remove_all_containers:
       docker container rm $(docker ps -aq) -f

I get the error message:

host_name$ make remove_all_containers
docker container rm  -f
"docker container rm" requires at least 1 argument.
See 'docker container rm --help'.

Usage:  docker container rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers
make: *** [remove_all_containers] Error 1

Clearly, when executed from within the makefile, the "docker ps" command is not being properly being properly executed in a way where its results can be collected and passed into the "container rm" command.

My Question: How do I get the "docker ps" command to run correctly from within the makefile and pass its results correctly into the "docker rm" command, also within the makefile?

Thanks, in advance, for any assistance you can offer.



Solution 1:[1]

You need a second $ in your recipe:

remove_all_containers:
       docker container rm $$(docker ps -aq) -f
#                           ^

The single $ is expanded as a makefile variable when the makefile is parsed. It expands to blank. Make therefore passes docker container rm -f to your shell. The second $ sign causes make to expand $$ to $, and it will pass docker container rm $(docker ps -aq) -f to bash, which I'm guessing is what you want.

Notice, if you put the shell in there as @EricMd proposed, it will run a shell command, but that command will be run at Makefile read time, as opposed to the time that the recipe is executed. If the docker ps -aq command is dependent on any other artifacts of your build it would not work.

Solution 2:[2]

Sounds like you don't have any containers in docker to remove. I sometimes use a different syntax for this scenario:

remove_all_containers:
       docker container ls -aq | xargs --no-run-if-empty docker container rm -f

The xargs syntax will not run docker container rm if there are no containers to delete.

Solution 3:[3]

According to the documentation, docker ps -a should list all containers.

You obtained this message "docker container rm" requires at least 1 argument certainly because you forgot to prepend the command at stake with Make's shell builtin:

remove_all_containers:
       docker container rm $(shell docker ps -aq) -f

Note also that the docker ps admits a filtering feature: the online doc describes the various flavors of the corresponding -f flag.

For example, below are three Bash alias examples that can be useful to (i) stop all containers, (ii) remove all stopped containers; and (iii) remove dangling images?that would be tagged as <none> when doing docker images ls:

alias docker-stop='docker stop $(docker ps -a -q)'
alias docker-clean='docker rm $(docker ps -a -q -f status=exited)'
alias docker-purge='docker rmi $(docker images -q -f dangling=true)'

Solution 4:[4]

I tested for 2 way follow bellow answer:

remove_all_containers:
   docker container rm $$(docker ps -aq) -f


remove_all_containers:
   docker container rm $(shell docker ps -aq) -f

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 BMitch
Solution 3
Solution 4 sun1211