I'm using a shell script that is trying to create a directory inside a container which is running. But it produces error as binary file not found.
Here is an example script:
#!/bin/sh
set -x
CONTAINER_ID=`docker ps | grep postgres | awk '{print $1}'`
docker exec -it $CONTAINER_ID bash mkdir /backup
Try this:
#!/bin/sh
set -x
CONTAINER_ID=`docker ps | grep postgres | awk '{print $1}'`
docker exec -it $CONTAINER_ID sh -c "mkdir /backup"
The sh -c "mkdir /backup" should work.
In case your docker image have bash inside it then try bash -c "mkdir /backup"
I tried from my end and got the desired result.
$ sh script.sh
+ docker ps
+ awk '{print $1}'
+ grep inspiring_sinoussi
+ CONTAINER_ID=08a35fa3c040
+ docker exec -it 08a35fa3c040 sh -c 'mkdir /backup'
$ docker exec -it 08a35fa3c040 sh
/ # ls / | grep backup
backup
Related
I've written a script to backup my docker mysql containers:
export $(grep -v '^#' .env | xargs -d '\n')
filename=$(date +'%Y%m%d_%H%M%S')
docker-compose exec mysql bash -c "mysqldump --user=$MYSQL_USERNAME --password='$MYSQL_PASSWORD' --ignore-table=$MYSQL_DATABASE.forums_readData_forums_c --ignore-table=$MYSQL_DATABASE.forums_readData_newPosts $MYSQL_DATABASE | gzip > /tmp/$filename.gz"
mysql_container=$(docker ps | grep -E 'mysql' | awk '{ print $1 }')
docker cp $mysql_container:/tmp/$filename.gz $BACKUP_DIR/mysql/
docker-compose exec mysql rm /tmp/$filename.gz
sudo find $BACKUP_DIR/mysql/* -mtime +30 -exec rm {} \;
But when I add it to the crontab, I get the error the input device is not a TTY. That's coming from the docker-compose exec command, except there's no -it flag? When I run this script directly from the shell ./backup.sh, it works fine.
I'm executing this command from docker host which is finally not giving me any error on stdout. And completes successfully on prompt but doesn't executes what it is supposed to do inside container.
Can someone please help me identify what am i doing wrong?
docker exec -dt SPSSC /bin/bash -c "grep -ril 'LOCALIZATION_ENABLED="false"' /opt/tpa/confd/config/* | grep -v 'diameter' | xargs sed -i 's/LOCALIZATION_ENABLED="false"/LOCALIZATION_ENABLED="true"/g'"
File name: dockerHandler.sh
#!/bin/bash
set -e
to=$1
shift
cont=$(docker run -d "$#")
code=$(timeout "$to" docker wait "$cont" || true)
docker kill $cont &> /dev/null
docker rm $cont
echo -n 'status: '
if [ -z "$code" ]; then
echo timeout
else
echo exited: $code
fi
echo output:
# pipe to sed simply for pretty nice indentation
docker logs $cont | sed 's/^/\t/'
docker rm $cont &> /dev/null
But whenever I check the docker container status after running the the docker image it is giving list of exited docker containers.
command: docker ps -as
Hence to delete those exited containers I am running manually below command
rm $(docker ps -a -f status=exited -q)
You should add the flag --rm to your docker command:
From Docker man:
➜ ~ docker run --help | grep rm
--rm Automatically remove the container when it exits
removed lines
docker kill $cont &> /dev/null
docker rm $cont
docker logs $cont | sed 's/^/\t/'
and used gtimeout instead timeout in Mac, it works fine.
To install gtimeout on Mac:
Installing CoreUtils
brew install coreutils
In line 8 of DockerTimeout.sh change timeout to gtimeout
I've been trying to execute bash on running docker container which has specific name as follows. --(1)
docker ps | grep somename | awk '{print $1 " bash"}' | xargs -I'{}' docker exec -it '{}'
but it didn't work and it shows a message like
"docker exec" requires at least 2 argument(s)
when I tried using command as follows --(2)
docker ps | grep somename | awk '{print $1 " bash"}' | xargs docker exec -it
it shows another error messages like
the input device is not a TTY
But when I tried using $() (sub shell) then it can be accomplished but I cannot understand why it does not work with the two codes (1)(2) above (using xargs)
Could any body explain why those happen?
I really appreciate any help you can provide in advance =)
EDIT 1:
I know how to accomplish my goal in other way like
docker exec -it $(docker ps | grep perf | awk '{print $1 " bash"}' )
But I'm just curious about why those codes are not working =)
First question
"docker exec" requires at least 2 argument(s)
In last pipe command, standard input of xargs is, for example, 42a9903486f2 bash. And you used xargs with -I (replace string) option.
So, docker recognizes that 42a9903486f2 bash is a first argument, without 2nd argument.
Below example perhaps is the what you expected.
docker ps | grep somename | awk '{print $1 " bash"}' | xargs bash -c 'docker exec -it $0 $1'
Second question
the input device is not a TTY
xargs excutes command on new child process. So you need to reopen stdin to child process for interactive communication. (MacOS: -o option)
docker ps | grep somename | awk '{print $1 " bash"}' | xargs -o docker exec -it
This worked for me:
sudo docker ps -q | xargs -I'{}' docker exec -t {} du -hs /tmp/
The exec command you run is something like this:
docker exec -it 'a1b2c3d4 bash'
And that is only one argument, not two. You need to remove the quotes around the argument to docker exec.
... | xargs -I'{}' docker exec -it {}
Then you will exec properly with two arguments.
docker exec -it a1b2c3d4 bash
------ ---
first arg ^ ^ second arg
I need to clear cache manually in my nginx docker container and would make a script, i have make a script that found the PID:
docker-pid
#!/bin/sh
exec docker inspect --format '{{ .State.Pid }}' "$#"
And another final script
clear_cache.sh
#!/bin/sh
PID=/usr/bin/docker-pid proxy_nginx_1
nsenter -m -p -u -n -i -t $PID
rm -rf /etc/nginx/cache/*
exit
I get this error:
./clear_cache.sh: line 2: proxy_nginx_1: command not found
if i launch docker-pid to shell, it works....Why?
In bash you have to use $(<COMMAND>) if you want to save the output of a command to a variable. So
clear_cache.sh
#!/bin/sh
PID=$(/usr/bin/docker-pid proxy_nginx_1)
nsenter -m -p -u -n -i -t $PID
rm -rf /etc/nginx/cache/*
exit
or
#!/bin/sh
PID=$(docker inspect --format '{{ .State.Pid }}' "$#")
nsenter -m -p -u -n -i -t $PID
rm -rf /etc/nginx/cache/*
exit