subtleseeker
subtleseeker

Reputation: 5273

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

Upvotes: 3

Views: 3375

Answers (1)

Matt
Matt

Reputation: 74841

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 [email protected] 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

Upvotes: 3

Related Questions