Parallels script help

krichterjr
Contributor

I'm working on cleaning up our licensing for Parallels as we have a few different license keys that have been used over the years.

I'm trying to build an Extension Attribute that either provides me the key or tell me it's "wrong". If the license key is the correct one it will have a line "key_number=" and the key will begin with "PDEI". If it doesn't have the correct key, this line either won't exist or the key will be something other than "PDEI".

I'm a total rookie at scripting so what I've put together is purely by piecing together other scripts with a whole lot of trial and error. Here is what I've come up with so far.

PDKey=$(prlsrvctl info --license | grep 'key_number' | awk '{print $1}')

if [ $PDKey -eq 0 ];
then
echo "<result>Wrong</result>"
else
echo "<result>$PDKey</result>"
fi

This is the error I get on a machine with the correct key:

-bash: [: key_number="PDEI.xxxxxxxx.xxxxx": integer expression expected
<result>key_number="PDEI.xxxxxxxx.xxxxx"</result>

This is the error I get on a machine with an incorrect key:

-bash: [ -eq: unary operation expected
<result></result>

I would be truly greatfull if anyone is able to help me clean this up or has an easier way to do this.

Thanks!

Kenny

1 ACCEPTED SOLUTION

mm2270
Legendary Contributor III

My mistake on not explaining one additional thing. To use =~, you need to use double bracket notation, like this:

if [[ "$PDKey" =~ "PDEI" ]];
then
    echo "Yes"
else
    echo "No"
fi

Give it a try with the double brackets. it should work. The single brackets will give you the 'binary operator expected' error you saw. I actually make it a habit of using double brackets for nearly all evaluation stuff in scripts. There are far fewer instances where single brackets works than when it fails.

Edit: to answer your other question, you can use either cut or awk with a field definition to grab only the piece of data you want.

For example, if the string that gets returned is: key_number="PDEI.12345678.12345"
You can try one of the following:

PDKey="key_number="PDEI.12345678.12345""
echo "$PDKey" | cut -d= -f2
PDEI.12345678.12345

Explanation: -d= defines "=" as a field separator, -f2 tells the cut command to cut and print the second field based on the defined field separator.

PDKey="key_number="PDEI.12345678.12345""
echo "$PDKey" | awk -F= '{print $2}'
PDEI.12345678.12345

Explanation: -F= defines "=" as the field separator. '{print $2}' tells awk to use the defined field separator and print the second column. You could also use '{print $NF}' - print last column and get the same result.

Either one should spit out just the key and not the initial key_number string. As always there are probably 6 other ways you can do it.

View solution in original post

7 REPLIES 7

mm2270
Legendary Contributor III

The error messages are telling you what the issue is. You're trying to equate a key with alpha and digits in it to "0". Essentially, you're asking the shell to do a math operation on something that is actually not a number. Why the if [ $PDKey -eq 0 ] line? Were you trying to test for a null value perhaps?
You can do a few things here to correct this. If you're certain that a correct key will have "PDEI" as part of the string, and an incorrect one will never have that, you can try using a "like" operator instead.

if [ $PDKey =~ "PDEI" ];

That would tell it to evaluate the string returned to see if "PDEI" is part of it somewhere. The =~ is different than == in that only part of the string must match to evaluate as 'true'

You can probably also check for a null value, but you mentioned that its possible an incorrect key may exist, in which case testing for null isn't going to be as accurate, I think. I don't use Parallels, so I'm taking guesses here. I have no idea how the licensing keys are set up.

krichterjr
Contributor

Thanks for the post. Your explanation is easier to understand that some of the 'man' pages I've tried to interpret.

Yes, my if [ $PDKey -eq 0 ] is trying to say if that line does not exist, tell me it's wrong (another script I was borrowing from used a simliar expression).

I changed that line to if [ $PDKey =~ "PDEI" ]; and it returned this error. Again, it's all quite new to me.

-bash: [: =~: binary operator expected
<result>key_number="PDEI.xxxxxxxx.xxxxx"</result>

I think the simplest way for me to do this is to just return the key_number through this command.

prlsrvctl info --license | grep 'key_number' | awk '{print $1}'

Which gives me this

key_number="PDEI.xxxxxxxx.xxxxx"

From there I can scope a Smart Group to determine if the key is right or not. My only problem is if the key_number does not exist, then the Extension Attribute may be left blank. I would rather have something returned so I can scope the Smart Group to look for that as opposed to using the "is not like". Not a real big deal though.

I guess I do have one last question (this is for my own knowledge). Is there a way to have the command only include the

PDEI.xxxxxxxx.xxxxx
and not the
key_number=
I know if there are spaces I can use the awk '{print $x}' but haven't figured out how to remove the other rubbish.

Thanks again for your help. :)

mm2270
Legendary Contributor III

My mistake on not explaining one additional thing. To use =~, you need to use double bracket notation, like this:

if [[ "$PDKey" =~ "PDEI" ]];
then
    echo "Yes"
else
    echo "No"
fi

Give it a try with the double brackets. it should work. The single brackets will give you the 'binary operator expected' error you saw. I actually make it a habit of using double brackets for nearly all evaluation stuff in scripts. There are far fewer instances where single brackets works than when it fails.

Edit: to answer your other question, you can use either cut or awk with a field definition to grab only the piece of data you want.

For example, if the string that gets returned is: key_number="PDEI.12345678.12345"
You can try one of the following:

PDKey="key_number="PDEI.12345678.12345""
echo "$PDKey" | cut -d= -f2
PDEI.12345678.12345

Explanation: -d= defines "=" as a field separator, -f2 tells the cut command to cut and print the second field based on the defined field separator.

PDKey="key_number="PDEI.12345678.12345""
echo "$PDKey" | awk -F= '{print $2}'
PDEI.12345678.12345

Explanation: -F= defines "=" as the field separator. '{print $2}' tells awk to use the defined field separator and print the second column. You could also use '{print $NF}' - print last column and get the same result.

Either one should spit out just the key and not the initial key_number string. As always there are probably 6 other ways you can do it.

PeterClarke
Contributor II

NB: if you wanted to use the:

if [ $PDKey =~ "PDEI" ] method, then I think you just need to change this to: if [[ $PDKey =~ "PDEI" ]]

ie with double brackets [[ and ]]

krichterjr
Contributor

Awesome! The double brackets worked and the information on 'cut' & 'awk' are very helpful. I really appreciate your explanations as well. I owe you a beverage if we ever meet. Thanks!

rmanly
Contributor III

Also, you almost never need to chain a grep and awk or sed.

PDKey=$(prlsrvctl info --license | awk -F= '/key_number/{ print $2 }')

mm2270
Legendary Contributor III

I was gonna mention awk's regex matching as well, but didn't want to throw too much info at him at once :)