13

I can't figure out how to make this (what supposed to be simple) script to work. Basically what I want, to run different stuff based on the state of my Parallels vm, something like this:

if [ prlctl list --info ubuntu-vm | grep State == "State: running" ] ; then 
   echo 'machine is running'
else
   echo 'machine is not running'
fi

Of course that doesn't work

iLemming
  • 647
  • 3
  • 7
  • 19

3 Answers3

20

The problem is that you are putting it all within [, i.e. the test command. Moreover, your usage of grep is broken.

All you need is:

if prlctl list --info ubuntu-vm | grep -q "State: running"; then
   echo 'machine is running'
else
   echo 'machine is not running'
fi

Note the usage of -q as an argument to grep. It doesn't write anything to STDOUT and exits with a status of 0 if the match is found, and non-zero otherwise.

devnull
  • 3,305
  • 2
  • 16
  • 23
  • 1
    A oneliner: `prlctl list --info ubuntu-vm | grep -q "State: running" && echo "machine is running" || echo "machine is not running"` – Noam Manos Jul 31 '19 at 12:03
5

An alternative check, less "clean" but closer to what the question tried to achieve.

Remember that [ at its core is just a command. It always accepts a specific number of parameters, and exits with either 0 (success) or 1 (failure) exit status, as all other commands do. For example, when you're comparing two strings, the syntax is[, string 1, ==, string 2, ].

Right now you're using this as the if condition:

[ prlctl list --info ubuntu-vm | grep State == "State: running" ]

But it's ambiguous in several ways. How would [ know that on the left you have a command to run and not a fixed string? How would it know that the == is the string comparison operator, rather than just an argument to grep? How would it know that the | is part of the left-hand value, rather than separating the command into [ prlctl list --info ubuntu-vm and grep State == "State: running" ]?

So the left side needs to be quoted as well. Also, since you want to compare the output of that command, rather than the worlds "prctl list --info..." themselves, you need the $(…) operator:

[ "$(prlctl list --info ubuntu-vm | grep State)" == "State: running" ]
u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • +1 for the detailed explanation. May I ask, Where have you gained you Shell-Scripting skills? I would love to read something about the Shell, that goes into that detail, like that `[` is a command, what probably seems very foreign to someone for whom knows only languages like Java or Python. – Senkaku May 07 '14 at 19:12
  • 1
    @Creaturo: It's a scripting language by design, intended to link together shell commands, so it makes sense that the `if` statement would accept an arbitrary command as the condition (`if ; then ; fi`). The syntax is described in `man bash` if you're working with the 'bash' shell. – u1686_grawity May 07 '14 at 19:30
  • This was a great answer! – Mercutio Sep 06 '18 at 21:24
0

IF we have below in txt files and want to grep multiple string.

minion1:

      ID: php_install
Function: pkg.installed
    Name: php
  Result: True
 Comment: All specified packages are already installed
 Started: 16:19:04.217642
Duration: 587.977 ms

We can use below grep statement:-

grep -Po '(ID|(?Function)|(?Duration)): (?(fun)\w+.\w+|(?(dur)\d+.\d+ ms|\w+))' high.yxy

To clarify above, I am doing

P means using pcre

o means it will give only the matches output

?<fun> its a name of function named group

I hope this will resolve your issue.