Efficiently compare If variable exists and is not equal

208

Strictly speaking, a variable does not exist if it has never been assigned a value, or if it has been unset. A variable with an empty string as value exists.

The standard parameter expansion ${variable+value} will substitute the string value when variable exists (is not unset or empty). This could be used to test for existence like this:

if [ "${OldIP+x}" = "x" ] && [ "$OldIP" != "$StartIP" ]; then
    # code
fi

To test whether OldIP exists in bash, use the -v test:

 if [[ -v OldIP ]] && [[ "$OldIP" != "$StartIP" ]]; then
     # code
 fi

This would perform the string comparison between $OldIP and $StartIP only if OldIP had been previously set (even if it was set to an empty string). Note that the -v test takes the name of the variable.

Share:
208

Related videos on Youtube

dvsn
Author by

dvsn

Updated on September 18, 2022

Comments

  • dvsn
    dvsn almost 2 years

    On a blog of mine, a user asked me if I could tell him his password from that account, which happens to be the same password he used on multiple accounts, on an email which was deactived - the point is he needs that specific password.

    Since the only option in the Wordpress Dashboard is to change the password, I had to look in phpmyadmin, under wp_users table at his password. The things is, the password is encrypted unde wordpress's unique encoding hash, phpass I believe, since it starts with $P$B. If it was 2008 again and wordpress would've used MD5 to enconde password in sql tables, it would have been easier.

    From my knowledge I know that phpass pasword can't be decrypted, naturally, since it's a one-way encryption method. The only way would be to bruteforce it, which is out of the question.

    And then, I thought about resending the user an e-mail containing the password. I searched the plugins page and found one named: 'Re-send Welcome e-mail' which still resets it eventualy. I think that this method is plausable, because, if I change the password in the wp_users table with another one encoded in phpass, he can login with the new one, so Wordpress somehow verifies it by encoding or decoding it, or by enconding it and comparing the hash of the password entered with the one already present in the wp_users table, under that user's row.

    Is there a plugin available or a turn-around to this situations? I overthinked the whole situation and now I'm out of solutions which are in my league of knowledge.

    • Jonathan Roberts
      Jonathan Roberts about 8 years
      You have two conditions that need to be checked, you need them both logically. However, many languages (including all shell scripts that i know of) will "short-circuit" the logical operators. If "$OLDIP" evaluated to false, the remainder of the expression won't be evaluated since it won't change the logic being tested.
    • Raphael Ahrens
      Raphael Ahrens about 8 years
      This sound like premature optimization. Have you profiled the script to make sure that this is really the bottleneck?
    • Pila
      Pila about 8 years
      Purely curiosity issue. I would like statement to be: if [[ "$OldIP" != "$StartIP" ]]; then echo OK; fi but it ignores non existance state of OldtIP
  • Alessio
    Alessio about 8 years
    ! -z "STRING" is the same as -n "STRING" (or just "STRING")
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' about 8 years
    Creating a subshell reduces the performance. { test … || test …; } && echo OK would do the same thing without creating a subshell. It wouldn't be a definite performance improvement over the original (maybe a slight difference one way or the other depending on the shell0.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' about 8 years
    Your proposal with ${OldIP:=unset} fails the value of StartIP is unset. If these are IP addresses as the name suggests, this won't arise, but it makes the code fragile: what if the script supports host names one day?
  • DrMartens
    DrMartens about 8 years
    Thank you Gilles, how ironic I would actually make it slower! I've updated my answer to reflect your hint.
  • Pankaj Goyal
    Pankaj Goyal about 8 years
    Easily fixed. I shall do so forthwith.
  • Stéphane Chazelas
    Stéphane Chazelas about 6 years
    busybox sh doesn't support -v. You can use [ "${OldIP+set}" = set ] there.
  • Kusalananda
    Kusalananda about 6 years
    @StéphaneChazelas Sorry, that's me not reading the tags and assuming this was for bash. My bad. Thanks for the suggestion.
  • user176181
    user176181 about 4 years
    I tried something similar in my code and bash complains: line 26: [: missing `]' if [ -z "$nextarg" || "$nextarg" =~ ^-[[:alnum:]]$ ]; then ( test if nextarg is either empty, or a "switch" (a minus and one alphanumeric char afterwards). I wonder what's wrong...
  • Kusalananda
    Kusalananda about 4 years
    @user176181 Note the use of [[ ... ]] around the test.