For example, suppose I have a container which needs the NET_ADMIN capability (keepalived as a container for example).
How can I check, when the container is run, that the capability is actually provided, so that I can add a log / throw an error?
You can commands to check the capabilities
$ capsh --print | grep "Current:" | cut -d' ' -f3 | grep -q cap_net_admin
$ echo $?
0
$ capsh --print | grep "Current:" | cut -d' ' -f3 | grep -q cap_net_admins
$ echo $?
1
Below command shows all available capabilities for a container
$ capsh --print | grep "Current:" | cut -d' ' -f3
cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+eip
Related
Having docker ps -a
I want to match the NAMES VERSION and STATUS.
docker ps -a --format "{{.Image}}\t{{.Status}}" | awk -F$"\t" '{printf "%s|%s\n", $1, $2}'
Output:
registry.com/project/glass/glass_front:2.2.15.4|Up 6 days
registry.com/project/glass/glass_proxy:2.2.15.4|Up 6 days
registry.com/project/glass/glass_modeles_front:2.1.5.2|Up 6 days
How can i modify my command to have this:
glass_front | 2.2.15.4 | Up 6 days
glass_proxy | 2.2.15.4 | Up 6 days
glass_modeles_front| 2.1.5.2 | Up 6 days
Try using colon as the separator in the docker ps command, then use sed to transform the colon to pipe and remove the prefix:
docker ps -a --format "{{.Image}}:{{.Status}}" \
| sed -e 's/:/ | /g' -e 's,^.*/,,'
Could you please try following, not tested it as don't have docker command. Its based on completely shown sample output of OP only.
docker ps -a --format "{{.Image}}\t{{.Status}}" \
| awk -F'\t' '{num=split($1,arr,"[/:]");print arr[num-1],arr[num],$2}'
OR(only using field separator capability of awk)
docker ps -a --format "{{.Image}}\t{{.Status}}" \
| awk -F"[/:\t]" '{print $4,$5,$NF}'
Explanation(1st solution): Running docker program(what OP shown) then passing its output as an input to awk command. In awk command setting field separator as TAB. Then splitting 1st field into an array(arr) with delimiter of /,:, then finally printing arr's 2nd last and last items here with 2nd field of current line.
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
The following command does not correctly capture the 16714 from 16714 ssh -f -N -T -R3300:localhost:22
egrep -o '^[^ ]+(?= .*[R]3300:localhost:22)'
(However swapping to grep does if you use the -P flag. I was expecting egrep to be able to handle this)
grep -P forces grep to use the Perl regexp engine.
egrep is the same as grep -E and it forces grep to use the ERE (extended regular expression) engine, that does not support lookahead.
You can find a quick reference of the differences between Perl and ERE (and others) here : http://www.greenend.org.uk/rjk/tech/regexp.html
To handle this with POSIX grep, you would use grep to isolate the lines of interest and then use cut to isolate the fields of interest:
$ echo "16714 ssh -f -N -T -R3300:localhost:22" | grep 'R3300:localhost:22' | cut -d' ' -f1
16714
Or, just use awk:
$ echo "16714 ssh -f -N -T -R3300:localhost:22" | awk '/R3300:localhost:22/{print $1}'
16714
docker client for docker ps has very useful flag -l which shows container information which was run recently. However all other docker commands requires providing either CONTAINER ID or NAME.
Is there any nice trick which would allow to call:
docker logs -f -l
instead of:
docker logs -f random_name
You can you docker logs -f `docker ps -ql`
For the last container
docker ps -n 1
or variants such as
docker ps -qan 1
can be handy
After a while playing with docker tutorial, I created small set of aliases:
alias docker_last="docker ps -l | tail -n +2 | awk '{ print \$(NF) }' | xargs docker $1"
alias docker_all="docker ps -a | tail -n +2 | awk '{ print \$(NF) }' | xargs docker $1"
alias docker_up="docker ps | tail -n +2 | awk '{ print \$(NF) }' | xargs docker $1"
alias docker_down="docker ps -a | tail -n +2 | grep -v Up | awk '{ print \$(NF) }' | xargs docker $1"
Which allow to call command on last, all, up and down containers:
docker_last logs # Display logs from last created container
docker_down rm # Remove all stopped containers
docker_up stop # Stop all running containers
Consider this example chain:
cat foo.txt | grep -v foo | grep -v bar | grep -v baz
I'd like to inspect the contents stdout of the second grep as well as the resulting stdout:
cat foo.txt | grep -v foo | grep -v bar | UNKNOWN | grep -v baz
So I need a tool, UNKNOWN, that for instance dumps the contents of stdout to a file and also passes stdout along the chain.
Does the tool, UNKNOWN, exists (both Windows and Linux answers are relevant) ?
I think there's a thing call 'tee' that gives you that.
Update reflecting comment from Bob:
cat foo.txt | grep -v foo | grep -v bar | tee -a inspection.txt | grep -v baz
Unable to give it a shot, but like Gabriel and Bob pointed out, the command $ tee (man tee) will help you out. The tee command will take input and echo it to stdout, as well as files. As Bob said in his comment:
cat foo.txt | grep -v foo | grep -v bar | tee -a inspection.txt | grep -v baz
Will take the output from grep -v bar and put it to stdout, as well as inspection.txt. The -a flag causes it to append to inspection rather than create a whole new file.