An alternative check, less "clean" but closer to what the question tried to achieve.
[ 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
[ 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
[ "$(prlctl list --info ubuntu-vm | grep State)" == "State: running" ]