I am trying to accomplish the following in one line:
<command> | xargs -I {} grep {} <(other command)>
I have a Kubernetes cluster which is running Redis and many other applications. I want to find out which applications (pods in this case) are connected to Redis.
This can be broken down in two steps.
- Getting the list of IPs connected to Redis.
- Get the pod names that holds those IPs.
I got the list of IPs with the following command:
$ kubectl exec -it redis -- redis-cli -a <redis-auth> client list | tail -n +2 | awk -F '[:= ]' '{ print $4 }' | sort | uniq > test.txt
$ cat test.txt
10.52.1.194
10.52.1.91
10.52.2.44
10.52.3.223
127.0.0.1
And I can also get the pod names with the following command:
$ grep -f test.txt <(kubectl get pods -o wide)
app1 1/1 Running 0 9d 10.52.1.91 node-8 <none> <none>
app2 2/2 Running 0 79d 10.52.2.44 node-14 <none> <none>
app3 2/2 Running 2 79d 10.52.1.194 node-11 <none> <none>
app4 1/1 Running 0 5d10h 10.52.3.223 node-30 <none> <none>
I want to accomplish both of these in one line. I tried the following:
$ kubectl exec -it redis -- redis-cli -a <redis-auth> client list | tail -n +2 | awk -F '[:= ]' '{ print $4 }' sort | uniq | xargs -t -I{} grep {} <(kubectl get pods -o wide)
it prints the following commands (that should be performed) but only performs the the first command:
grep 10.52.1.194 /dev/fd/63
app3 2/2 Running 2 79d 10.52.1.194 node-11 <none> <none>
grep 127.0.0.1 /dev/fd/63
grep 10.52.1.91 /dev/fd/63
grep 10.52.2.44 /dev/fd/63
grep 10.52.3.223 /dev/fd/63
How can I accomplish this in one line. Also, I am aware that I can give an name
to each client that is connecting to Redis but it requires changing the application code which I can’t do right now.
Edit:
The one-liner given by me actually partially works as in it only performs the first grep ...
instead of all the grep ...
commands. Can anyone explain what am I doing wrong here?
Edit2:
My hypothesis that only the first grep command works is that somehow after the first grep command, /dev/fd/63
probably points to a non-existing or empty file. Also, the following command works for some reason. Can anyone explain?
$ kubectl exec -t redis -- redis-cli -a <redis-auth> client list | tail -n +2 | awk -F '[:= ]' '{ print $4 }' | sort -u | xargs -t -I{} bash -c 'grep -w {} <(kubectl get pods -o wide)'
bash -c grep -w 10.52.1.194 <(kubectl get pods -o wide)
app3 2/2 Running 2 80d 10.52.1.194 node-11 <none> <none>
bash -c grep -w 10.52.1.91 <(kubectl get pods -o wide)
app1 1/1 Running 0 10d 10.52.1.91 node-8 <none> <none>
bash -c grep -w 10.52.2.44 <(kubectl get pods -o wide)
app2 2/2 Running 0 80d 10.52.2.44 node-14 <none> <none>
bash -c grep -w 10.52.3.223 <(kubectl get pods -o wide)
app4 1/1 Running 0 6d10h 10.52.3.223 node-30 <none> <none>
2
Answers
Can you try this one :
If you have problems, trouble-shoot with this command first :
Try simply:
Or same:
Note 1: This is still one line, you could cut’n paste and even drop newlines. Just easier to re-read.
Note 2:
sort | uniq
could be simplified bysort -u
:But you could event write this:
Could be re-writted in two lines:
or