0

In reference to this question I still struggle the following single-liner to work

kubectl get ns | while read -r line; do  echo `$line | grep Term | cut -d' ' -f1`; done

I would expect to print out the result of $line | grep Term | cut -d' ' -f1 however it prints out an empty line (echo) and then executes the result of $line | grep Term | cut -d' ' -f1

bash: NAME: command not found

bash: cert-manager: command not found

bash: configmap-4262: command not found

bash: configmap-4430: command not found

Same results with a slightly different approach:

kubectl get ns | while read -r line; do ns=`$line | grep Term | cut -d' ' -f1`; echo $ns; done

What I actually want to achieve is to use the result of $line | grep Term | cut -d' as an input of a shell script e.g.

do ns=`$line | grep Term | cut -d' ' -f1`; ./delete-kube-ns.sh $ns;

or

$line | grep Term | cut -d' ' -f1` | xargs ./delete-kube-ns.sh
2
  • 1
    You're trying to execute the contents of $line as a shell command. Commented Feb 14, 2020 at 16:38
  • To expand on the previous comment, if $line is poo, then the command $line | grep tries to execute poo and pipe its output to grep. You apparently want echo "$line" | grep etc; pay attention to the quotes around the variable, too. Code which doesn't do what you want is often a poor way to explain what you do want. Commented Feb 15, 2020 at 18:41

4 Answers 4

3

Ger rid of the backticks. It's trying to execute the output of kubectl as a shell command. You want to echo $line, not the result of executing it as a command.

kubectl get ns | while read -r line; do  
    echo "$line" | grep Term | cut -d' ' -f1
done

There doesn't really seem to be a need to use while read at all, just pipe kubectl to grep

kubectl get ns | grep Term | cut -d' ' -f1
Sign up to request clarification or add additional context in comments.

1 Comment

Yeah maybe my question was not properly enough, the echo was just an example for me on the way to get an understanding. What I want in the end is to something like this do ns=`$line | grep Term | cut -d' ' -f1`; ./delete-kube-ns.sh $ns;
1

A parameter expansion might be what you want/need, instead of embedding grep and cut inside a while read loop.

#!/usr/bin/env bash

kubectl get ns | while IFS= read -r line; do  
  [[ $line == Term ]] && ns=${line% *}
  echo "$ns"
done

Depending on the pattern match, you might need *Term*

1 Comment

kubectl get ns | awk '/Term/{print $1}'
1

Any combo of grep and cut (and head, tall, etc, as well as sed) suggests a reimplementation in Awk. Saving one external process is a minor optimization, but this often invites additional simple improvements. For example, should the regex cover the whole line, or is it only really supposed to look for matches in the first field? That's not impossible with grep, either, of course, but quite easy in Awk.

kubectl get ns |
awk '/Term/ { print $1 }'

If you only wanted to look for Term in the first field, that's '$1 ~ /Term/ { ...

You can extend this with a pipe to

... | xargs ./delete-kube-ns.sh

if that's your end goal.

Comments

0

With your suggestion I actually could achieve what I intended to do

kubectl get ns | awk '/Term/ { print $1 }' | while IFS= read -r line; do
   ~/bin/kill-kube-ns.sh $line
done
Killed namespace: configmap-4500
Killed namespace: configmap-5062
Killed namespace: configmap-5526
Killed namespace: configmap-5817
Killed namespace: configmap-6143

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.