0

Context:

I want to check whether a kubernetes pod is already running. For this i am using a while loop to get the output of kubectl. Then I look for the appropriate status.

Observation:

A dummy pod is running just like this:

kubectl get pods
# dummy-7744bb4469-h2mrq   1/1  Running   0   58d

Now i execute the following command in the cli and it returns the above line containing the dummy pod

kubectl get pods | grep dummy* 
# dummy-7744bb4469-h2mrq   1/1  Running   0   58d
# with "dummy" being color highlighted

So i created a while loop in a bash script which looks like this:

function check_pod_running(){
   while [ $(kubectl get pods | grep $1* | grep Running | wc -l) == 0]; ...
}
# with $1 being the string dummy

However it can not grep the appropriate line and is stuck in the loop until timeout.

Using google i found this Using the star sign in grep post, which tells me to use $1.* instead of $1* and it does work, but I'd like to know why in my case? Why does it work in the cli but not in a script which executes the same command?

Edit: Solved

Thanks to Charles Duffy and his hint, that a normal unquoted grep will first look into the current directory before the piped output. The script which was running the abovementioned grep was also executing a pushd at some point, changing the current directory which coincidentally also included a file with "dummy" in its name. Apparently, it would then expand on the filename and would grep dummy.txt from the piped output of kubectl, which yields nothing.

Hung
  • 41
  • 2
  • `dummy*` matches `dumm`, `dummy`, `dummyy`, `dummyyy`, etc. Are you sure the `y*` (meaning "zero or more `y`s) is really what you want? – Charles Duffy Jun 23 '22 at 11:20
  • Also, because it's unquoted, it'll get replaced with a list of filenames in the local directory that start with `dummy` _before_ grep is started unless you make it `grep "dummy*"` or `grep "$1*"`, _with the asterisk included in the quotes_. – Charles Duffy Jun 23 '22 at 11:21
  • BTW, `function funcname() {` merges legacy ksh and POSIX sh syntax in a way that's incompatible with *both* legacy ksh and POSIX. Best practice is just `funcname() {` with no `function`; see https://wiki.bash-hackers.org/scripting/obsolete – Charles Duffy Jun 23 '22 at 11:22
  • Anyhow -- to see what exactly the pipeline in the loop really does in practice, run your script with `bash -x yourscript dummy` and watch the trace log that's generated. If the script is executing the grep in a directory that has a `dummy.txt` so `dummy*` is being replaced with `dummy.txt`, you'll see the replacement when it logs the `grep` command line it's running. – Charles Duffy Jun 23 '22 at 11:23
  • BTW, if your real goal in `dummy*` is to match any string that starts with `dummy`, then the expression you want is `'^dummy'`, anchoring to the front of the line. – Charles Duffy Jun 23 '22 at 11:24
  • If the core of your question is not grokking the difference between regexes that grep takes and glob-style patterns, then [What are the differences between glob-style patterns and regular expressions?](https://stackoverflow.com/questions/23702202/what-are-the-differences-between-glob-style-pattern-and-regular-expression) may be relevant. – Charles Duffy Jun 23 '22 at 11:26
  • ...so the reason `dummy.*` is correct instead of `dummy*` is because grep takes regular expressions, and in a regex `*` means "change the preceding token to be recognized zero-or-more times"; not "match anything any number of times" as it means in glob expressions. Two completely different types of expression. And whereas in a glob `.` matches itself, in a regex it means "match any character", so `.*` means "match any character" (from the `.`) "any number of times, including zero" (from the `*`). – Charles Duffy Jun 23 '22 at 11:31
  • While i appreciate the very fast and supportive answer, i admittingly still not seee whether it answers my questions, because in both cases (in cli and in a bash script) i use the exact same grep command, but get different results. That being said, i really appreaciate your valueable hints! – Hung Jun 23 '22 at 11:43
  • If you use `set -x` tracing as suggested above you'll see _why_ you get different results. Until I see that trace, I don't know why either (because I don't know the filenames on your hard drive, don't know which directories the two instances run in, etc). – Charles Duffy Jun 23 '22 at 11:45
  • ...whereas if you fix the quoting as suggested above (and in the linked duplicate about quoting), then those details should stop making a difference and you're more likely to get consistent behavior between the CLI and your script. – Charles Duffy Jun 23 '22 at 11:46
  • (There are other shell settings that could result in inconsistent behavior -- if your script has the `nullglob` setting and your interactive shell doesn't, f/e -- but of effects those too will be visible in the `bash -x` trace, and are likewise mostly addressed by adding the missing quotes). – Charles Duffy Jun 23 '22 at 11:47
  • Thank you Charles Dufy for your patience, you were absolutely right! I tried the procedure on a separete script and it did not throw the error as described but then tried again on the original one. Because in this script at some point pushd has been used, the current directory changed and concidentally there were indeed files containing dummy, which resulted in the behavior you described! The missing quotes did solve the problem, but i was rather curious what caused it. Thanks again for your patience! – Hung Jun 23 '22 at 11:56

0 Answers0