Unexpected behaviour from awk in docker-machine - awk

Inspired by this post, I'm attempting to use docker-machine on my Mac to stop a running container. However, awk appears to behave differently in docker-machine ssh than when run directly "in" the container.
When I'm ssh'd to the container directly, everything works as expected:
me#myMac:~$ docker-machine ssh default
docker#default:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
028fd7148881 myrepo/mycontainer "apachectl -DFOREGROU" 14 minutes ago Up 14 minutes 0.0.0.0:80->80/tcp gloomy_mayer
docker#default:~$ docker ps | awk 'NR > 1 {print $1}'
028fd7148881
docker#default:~$ docker ps | awk 'NR > 1 {print $1}' | xargs --no-run-if-empty docker kill
028fd7148881
docker#default:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
But when run remotely, awk behaves differently:
me#myMac:~$ docker-machine ssh default "docker ps"
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7927b10b8a28 myrepo/mycontainer "apachectl -DFOREGROU" 11 seconds ago Up 10 seconds 80/tcp happy_wozniak
me#myMac:~$ docker-machine ssh default "docker ps | awk 'NR > 1 {print $1}'"
7927b10b8a28 myrepo/mycontainer "apachectl -DFOREGROU" About a minute ago Up About a minute 80/tcp happy_wozniak
me#myMac:~$ docker-machine ssh default "docker ps | awk 'NR > 1 {print $1}' | xargs --no-run-if-empty docker kill"
7927b10b8a28
Failed to kill container (myrepo/mycontainer): Error response from daemon: Cannot kill container myrepo/mycontainer: No such container: myRepo/myContainer
Failed to kill container (apachectl -DFOREGROU): Error response from daemon: Cannot kill container apachectl -DFOREGROU: No such container: apachectl -DFOREGROU
Failed to kill container (3): Error response from daemon: Cannot kill container 3: No such container: 3
...
Why does awk behave differently under docker-machine?

"docker ps | awk 'NR > 1 {print \$1}' | xargs --no-run-if-empty docker kill"
$ ==> \$
docker ps -q

Related

How to download files(zip) from a server using scp command for a particular date?

I have a Linux server from which i need to download files(server contains many zipped files for a day) to my local machine that is generated for a particular day. is it possible to do so? please help. Thank you
suggesting 2 scripts
show-files.sh on server
#!/bin/sh
stat -c "%y %n" * | grep $1 | awk '{print $4}' > files.list
copy-files.sh on local machine
#!/bin/sh
ssh $1 ./show-files.sh $2
LIST=`ssh $1 cat files.list`
for f in $LIST
do
scp $1:$f ./
done
on local machine call
./copy-files.sh SERVER_IP 2023-01-13

AIX - How to kill using process name instead of PID

Is there a way to kill a process by specifying the process name instead of PID for AIX?
E.g. for the below process I want to kill it by specifying sapstartsrv instead of 10682424
hmsadm 10682424 1 0 Apr 30 - 0:54 /usr/sap/HMS/ASCS01/exe/sapstartsrv pf=/usr/sap/HMS/SYS/profile/START_ASCS01_H\
Thanks.
You can use command like this:
kill -9 $(ps -ef|grep sapstartsrv|awk '{print $2}')
of course first check if command ps -ef|grep sapstartsrv|awk '{print $2}' return only processes you want to kill
Try this. The brackets around the first letter of process you are trying to kill helps. Obviously change this to a valid server.
while true; do date; ping -c4 server; sleep 500; done &
ps -aef | grep -i [p]ing | awk '{print $2}' | xargs kill -9
If that doesn't work sometimes you have to kill the parent process.
ps -aef | grep -i [p]ing | awk '{print $2 " " $3}' | xargs kill -9

awk command not working with kubectl exec

From outside container:
$ kubectl exec -it ui-gateway-0 -- bash -c "ps -ef | grep entities_api_svc | head -1"
root 14 9 0 10:34 ? 00:00:02 /svc/bin/entities_api_svc
$ kubectl exec -it ui-gateway-0 -- bash -c "ps -ef | grep entities_api_svc | head -1 | awk '{print $2}'"
root 14 9 0 10:34 ? 00:00:02 /svc/bin/entities_api_svc
From inside container:
[root#ui-gateway-0 /]# ps -ef | grep entities_api_svc | head -1 | awk '{print $2}'
14
I find it easier to use single quotes on the sh/bash command argument so it is closer to what you would type in the shell:
kubectl exec -it ui-gateway-0 -- \
bash -c 'ps -ef | grep entities_api_svc | head -1 | awk "{print \$2}"'
This means the awk uses double quotes, which requires the shell variable marker $ to be escaped.
In the original command, the shell running kubectl was replacing $2 with a zero length string so awk would see only print, which prints the whole line
Multiple levels of nesting
Nested shell escaping gets very obscure very quickly and hard to debug:
$ printf '%q\n' 'echo "single nested $var" | awk "print $2"'
echo\ \"single\ nested\ \$var\"\ \|\ awk\ \"print\ \$2\"
$ printf '%q\n' "$(printf '%q\n' 'echo "double nested $var" | awk "print $2"')"
echo\\\ \\\"double\\\ nested\\\ \\\$var\\\"\\\ \\\|\\\ awk\\\ \\\"print\\\ \\\$2\\\"
If you add a file grep-entities.sh in container
#!/bin/bash
set -uex -o pipefail
ps -ef | grep entities_api_svc | head -1 | awk '{print $2}'
You then don't need to worry about escaping
pid=$(sshpass -p "password" ssh vm#10.10.0.1 kubectl exec ui-gateway-0 -- /grep-entities.sh)
Also pgrep does the scripts job for you
kubectl exec ui-gateway-0 -- pgrep entities_api_svc

Get all keys in Redis cluster

I am using Redis cluster version redis-5.0.5. I want to see all the keys present in my Redis cluster. I know for standalone we use KEYS * to get all the keys.
what is the way to see all keys in Redis cluster?
$ redis-cli -h hostname -p 90001 -c
hostname:90001> KEYS *
(empty list or set)
// I have data on my cluster
Basically, you'd need to run KEYS * (not in production, please!) on every one of the nodes. The cli can do this with the '--cluster call' command, like so:
redis-cli --cluster call hostname:90001 KEYS "*"
Requirement:
redis-cli
awk
grep
xargs
May be can try this assuming redis server reside in localhost with the default port 6379:
redis-cli cluster nodes | awk '{print $2" "$3}' | grep master | awk -F # '{print $1}' | awk -F : '{print " -h "$1" -p "$2" --scan"}' | xargs -L 1 redis-cli -c
Longer version base question above (90001 port number seriously?) and also you can change the pattern (* no filter) for filtering certain key pattern:
redis-cli -h hostname -p 90001 cluster nodes | awk '{print $2" "$3}' | grep master | awk -F # '{print $1}' | awk -F : '{print " -h "$1" -p "$2" --scan --pattern *"}' | xargs -L 1 redis-cli -c
It connects to any one of the redis node to get cluster info and then execute the keys scanning command on each of the master node.
The SCAN command may be what you're looking for, but it's O(N) so the more keys you have, the slower it's going to be. Also, check out this answer by Marc Gravell for another approach using sets: Get values by key pattern in StackExchange.Redis

How to kill a process in cygwin?

Hi i have the following process which i cant kill:
I am running cygwin in windows xp 32 bit.
I have tried issuing the following commands:
/bin/kill -f 4760
/bin/kill -9 5000
kill -9 5000
kill 5000
When i write /bin/kill -f 4760 i get the message, 'kill: couldn't open pid 4760'.
When i write /bin/kill -9 5000 i get the message, 'kill: 5000: No such process'.
I simply don't understand why this process cant be killed.
Since it has a WINID shouldnt it be killed by /bin/kill -f 4760?
hope someone can help thx :)
The process is locked from Windows most likely. The error you are getting "couldnt open PID XXX" points to this.
To confirm try killing it with windows taskkill
taskkill /PID 4760
Strangely, the following works in Cygwin:
echo PID1 PID2 PID3 | xargs kill -f
For example:
ps -W | grep WindowsPooPoo | awk '{print $1}' | while read line; do echo $line | xargs kill -f; done;
Different Windows programs will handle the signals that kill sends differently; they've never been designed to deal with them in the same way that Linux/Cygwin programs are.
The only reliable method for killing a Windows program is to use a Windows specific tool, such as Task Manager or Process Explorer.
That said, if you've not already, you may have luck with running your Cygwin terminal in administrator mode (right click on your shortcut and select "Run as administrator").
The method presented by #Donal Tobin is correct:
kill -f <pid>
However, I don't need to log in as administrator.
Create a file called killall.sh with this line
ps -W | grep $1 | awk '{print $1}' | while read line; do echo $line | xargs kill -f; done;
Then give it execute permissions.
chmod 777 killall.sh
In your .bash_profile add this line
alias killall="~/killall.sh" (point it to the correct location)
Then you just have to type "killall [name]"
killall.sh - Kill by process name.
#/bin/bash
ps -W | grep "$1" | awk '{print $1}' | xargs kill -f;
Usage:
$ killall <process name>
For me this command does not work on Windows 10 in Cygwin:
$ kill -f 15916
bash: kill: (15916) - No such process
Instead of it, you can use next commands:
$ powershell kill -f 15916
$ netstat -ano | grep ':8080' | awk '{print $5}' | xargs powershell kill -f
$ netstat -ano | grep ':8080' | awk '{print $5}' | while read pid; do powershell kill -f $pid; done;
$ netstat -ano | grep ':8080' | awk '{sub(/\r/,"",$5) ; print $5}' | while read pid; do taskkill /F /PID $pid; done;
SUCCESS: The process with PID 15916 has been terminated.