alias zsh: parse error near `do' - terminal

I'm facing an issue with an alias for zsh.
I've this alias in my .zprofile file: alias cleanimg="for i in `docker images | grep '<none>' | awk '{print $3}'`; do; docker rmi -f $i; done".
When running cleanimg from my terminal I'm getting this error: zsh: parse error near `do'.
I tried to remove the ; right after the do keyword but it didn't fix the issue.
However, that alias runs correctly if I execute the code directly from a terminal.
Can anybody help me with this syntax error?
Thanks by advance.

Don't try to use an alias for this; use a function.
cleanimg () {
for i in $(docker images | awk '/<none>/ {print $3}'); do
docker rmi -f "$i"
done
}
This saves you from having to get the quoting right so that the command substitution runs when the alias is used, rather than when it is defined.
(Also, grep | awk pipelines can almost always be implemented using awk alone.)
(I also wonder if you can dispense with awk and the loop using the --filters option instead; maybe docker rmi -f $(docker images -q -f "dangling=true")?)

If all you want is to clean your docker images, you can set an alias like this:
alias cleanimg='docker rmi -f $(docker images -q -f "dangling=true")'
The sub commande docker images -q -f "dangling=true" return all your id to remove and since docker rmi accept arguments you can pass them directly

You have an extra semicolon in your for loop, just fix it to -
alias cleanimg="for i indocker images | grep '' | awk '{print $3}'; do docker rmi -f $i; done"

Related

Issue in executing docker command in bash script

I have following bash script code try to run a docker container through bash script but I am retreiving error.
#!/bin/bash
name=sudo docker ps | grep 'test' | awk '{print
$1}'
sudo docker exec -it $name bash
error:
docker exec requires at least two arguments
Assuming that you have a docker container actually called test running, the way the id is attained is incorrect. In order to expand a command into a variable, it needs to be contained within $() and so:
#!/bin/bash
name=$(docker ps | grep 'test' | awk '{print $1}')
sudo docker exec -it $name bash
A further note is the fact that you don't need sudo permissions to run docker ps ...
Additionally, you never need to pipe grep into awk as awk can do this for you:
name=$(docker ps | awk '/test/ {print $1}')
Further more, there is no need to pipe at all given the native capabilities built into docker-ps and so:
name=$(docker ps -q -f name=test)
This will print only the container id of a container named test. I'm assuming that the name is test here but it could be something else i.e. the label that is named test, in which case the filter would need to change:
-f, --filter=[]
Filter output based on these conditions:
- exited=<int> an exit code of <int>
- label=<key> or label=<key>=<value>
- status=(created|restarting|running|paused|exited|dead)
- name=<string> a container's name
- id=<ID> a container's ID
- before=(<container-name>|<container-id>)
- since=(<container-name>|<container-id>)
- ancestor=(<image-name>[:tag]|<image-id>| â¨image#digestâ©) - conâ
tainers created from an image or a descendant.
- volume=(<volume-name>|<mount-point-destination>)
- network=(<network-name>|<network-id>) - containers connected to
the provided network

Nested quoting in bash

I'm connecting to a remote server via SSH:
ssh -i ~/.ssh/pk.pem user#server
and then, on that server, open bash within a Docker container:
docker exec -it $(docker ps | grep ecs-worker-low | cut -d ' ' -f1) bash
This works fine. (Note that I need to get the container ID like this. I'm not able to name the container.)
I would like to combine the two commands, so that I only run one command and get the shell within the container. This can be done with something like this:
ssh -i ~/.ssh/pk.pem user#server -t "bash -c 'docker exec -it $(docker ps | grep ecs-worker-low | cut -d ' ' -f1) bash'"
However this doesn't work because of the nested single quotes. I haven't found any way around this. Can you please help me? Thank you.
You can avoid the use of cut with --filter and --format
ssh -t -i ~/.ssh/pk.pem user#serve 'docker exec -it $(docker ps --filter ancestor=ecs-worker-low --format {{.ID}}) bash'
It's probably easiest to use a heredoc:
ssh -i ~/.ssh/pk.pem user#server -t << \EOF
docker exec -it $(docker ps | grep ecs-worker-low | cut -d ' ' -f1)
EOF
Make sure you use a non-interpolating heredoc. If you omit the backslash on the initial delimiter, the process substitution will be made on the local host.
Swap the quotes:
ssh -i ~/.ssh/pk.pem user#server -t 'bash -c "docker exec -it $(docker ps | grep ecs-worker-low | cut -d " " -f1) bash"'
All the double quotes are literal characters as far as ssh is concerned, and the command substitution creates a new context so that the first inner quote does not close the first outer quote. That said...
... Simplifying matters, you likely don't need the outer bash; ssh can run docker for you directly:
ssh -i ~/.ssh/pk.pem user#server -t 'docker exec -it $(docker ps | grep ecs-worker-low | cut -d " " -f1) bash'

Delete all docker instances at once

I'm new to dockers and other concepts. I've lots of unused dockers running and I would want to remove all of them. Now I'm manually killing it. Can we do it at once?
docker rm $(docker ps -a -q)
This command deletes all stopped containers. The command docker ps -a -q above returns all existing container IDs and passes them to the docker rm command which deletes them. Running containers are not deleted.
OR, try this one.
docker system prune -a
Remove all unused images not just dangling ones. also it will remove all build cache
As #Emon mentioned you can either go for docker prune. But keep in mind that pruning the system will remove any stopped containers and all unused images.
Since you've tagged shell, I'm adding this shell script also.
echo -e "******* Start *******"
echo -e "\n=====> Stopping & Cleaning up UNUSED containers.."
for i in `docker ps -a | grep -v CONTAINER | awk '{print $1}'`; do docker stop $i ; docker rm $i ; done
echo -e "[CLEARED]\n"
docker ps -a
echo -e "\n=====> Removing UNUSED container images.."
for i in `docker images | grep none | awk '{print $3}'`; do docker rmi $i ; done
echo -e "[CLEARED]\n"
docker images
This script can be changed accordingly to your need like if you want to remove only containers or even images also.
This can further also be done easily by
docker ps -a | grep "pattern" | awk '{print $1}' | xargs docker rm
If you want to remove only the exitted containers alone, you can use it
`docker rm $(docker ps -a -f status=exited -q)`

Shell script works from command line but not from cron

I am using https://stackoverflow.com/a/42955871/308851 and it works from command line but not from cron. I even tried running the script with env -i but it stubbornly works.
#!/bin/bash
filename=$(date '+%Y-%m-%d').gz
docker exec -t elastic_db.1.$(docker service ps -f 'name=elastic_db.1' elastic_db -q --no-trunc | head -n1) mysqldump example |gzip -9 > /container/$filename
docker exec -t elastic_drupal.1.$(docker service ps -f 'name=elastic_drupal.1' elastic_drupal -q --no-trunc |head -n1) rclone --config /etc/rclone.conf move /app/$filename example:example/dump/
This compresses a 0 byte file when ran from cron but works just fine otherwise. What am I doing wrong?
Gordon Davisson's comment is correct: changing docker to /usr/bin/docker worked.

Grep on docker image names in package.json

I want to set a script in the package.json that starts the container based on image-name that I grep after piping the docker images command, something like this:
"docker:run": "docker run -it -v /$(pwd):/app $(docker images | grep 'online-check-in-frontend' | awk '{ print $1 }') sh",
also tried :
"docker:run": "docker run -it -v /$(pwd):/app $(docker images | grep \"online-check-in-frontend\" | awk \"{ print $1 }\") sh",
The commands above is not working, i get the following error:
Im using windows, and bash. :S
Br

Resources