1

I'm new to bash scripting and I've been learning as I go with a small project I'm taking on. However, I've run into a problem that I cannot seem to get past.

I have a variable that I need to include in a command. When ran directly in the shell (with the variable manually typed), the command returns the expected result. However, I can't get it to work when using a variable.

So, if I manually run this, it correctly returns 0 or 1, depending if it is running or not.

ps -ef | grep -v grep | grep -c ProcessName

However, when I try to embed that into this while clause, it always evaluates to 0 because it's not searching for the correct text.

while [ `ps -ef | grep -v grep | grep -c {$1}` -ne 0 ]
do
  sleep 5
done

Is there a way I can accomplish this? I've tried a myriad of different things to no avail. I also tried using the $() syntax for command substitution, but I had no luck with that either.

Thanks!

4
  • 1
    Why do you have braces in your while loop's test, but not in your example? And does $1 have the correct value? Commented Feb 8, 2011 at 16:53
  • I put the braces in the while loop because I thought I needed them there to signify the variable. That may be incorrect, but removing them does not resolve the problem for me. And yes, $1 has the correct value. I added echo $1 right before the while statement and it is correct. Commented Feb 8, 2011 at 17:08
  • If you need to use curly braces, the dollar sign goes before the opening one and it's a good ideas to quote it, too: "${1}". Please see Process Management for some useful information. Commented Feb 8, 2011 at 17:18
  • 1
    You might also want to look at the parameter expansion section of the bash man page. The upshot is that $var is the same as ${var}; the latter is for cases like ${var}_suffix, since $var_suffix would be interpreted like ${var_suffix}. As Dennis says, the $ is always first. Commented Feb 8, 2011 at 18:01

2 Answers 2

3

I think that instead of {$1} you mean "$1". Also, you can just do pgrep -c "$1" instead of the two pipes.

In addition, there's also no need to compare the output of grep -c with 0, since you can just see if the command failed or not. So, a much simplified version might be:

while pgrep "$1" > /dev/null
do
    sleep 4
done
Sign up to request clarification or add additional context in comments.

5 Comments

I replaced {$1} with "$1" but that does not work either. I'm going to look over this to make sure I'm not missing something...
@grt3kl: Sorry, I got the sense of what you're trying to do wrong - I now realise that you're trying to sleep while a certain process is running, not to sleep until it starts. So, I've changed the example from until pgrep "$1" to while pgrep "$1", which certainly works for me here.
Can you explain what pgrep "$1" > /dev/null does? Actually, I understand it except for the arithmetic comparison. If I wanted to do the opposite (i.e., sleep while a certain process is not running), would it just be pgrep "$1" <= /dev/null or something different altogether?
> here isn't a comparison - it says to redirect the standard output of the command to the special file /dev/null, which basically means to throw it away. I added that because otherwise you'd see the output of the pgrep command whenever it runs.
I discovered that my problem was a bit more complex than I thought, but this answer is what led me to a solution. Many thanks!
1

You should really use -C with ps rather than the messy pipes if you're using the full process name. If you're interested in substring matching, then your way is the only thing I can think of.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.