Multiple string comparison in a single if statement shell script using OR gate [duplicate]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
-1
down vote

favorite













This question already has an answer here:



  • Using the not equal operator for string comparison

    6 answers



I am trying to compare the string stored in a variable with three different strings and if none of them match then throw an error. I've tried to do this in a single if statement using the logical operator OR. But every time I am getting error even though the value stored in the variable is same as one of the possible value. Please find the snippets I tried.



if [[ "$TYPE" != "LOCAL" || "$TYPE" != "REMOTE" || "$TYPE" != "BOTH" ]]; then
echo -e "ntINCORRECT OR NULL ARGUMENTS PASSED. PLEASE VERIFY AND CORRECT THE USAGE MENTIONED AS BELOW: n"
Usage
exit 1
fi


if [[ "$TYPE" != "LOCAL" ]] || [["$TYPE" != "REMOTE" ]] || [["$TYPE" != "BOTH" ]]; then
echo -e "ntINCORRECT OR NULL ARGUMENTS PASSED. PLEASE VERIFY AND CORRECT THE USAGE MENTIONED AS BELOW: n"
Usage
exit 1
fi






share|improve this question













marked as duplicate by Jesse_b, schily, G-Man, slm♦ shell-script
Users with the  shell-script badge can single-handedly close shell-script questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Jul 27 at 17:26


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.










  • 4




    you want && not ||
    – RoVo
    Jul 27 at 12:54











  • @RoVo I want OR because $TYPE has 3 possible values viz. LOCAL,REMOTE or BOTH and if doesn't matches with any of these 3 then it should throw error. Your suggestion please.
    – Mahendra
    Jul 27 at 12:58







  • 2




    TYPE cannot simultaneously be equal to LOCAL, REMOTE, and BOTH. In plain English, your use of OR says "If type is not local, OR if type is not remote, OR if type is not both, throw an error." What you probably want is "If type is not local, AND is not remote, AND is not both, then throw an error." See the difference?
    – Kevin Kruse
    Jul 27 at 13:08
















up vote
-1
down vote

favorite













This question already has an answer here:



  • Using the not equal operator for string comparison

    6 answers



I am trying to compare the string stored in a variable with three different strings and if none of them match then throw an error. I've tried to do this in a single if statement using the logical operator OR. But every time I am getting error even though the value stored in the variable is same as one of the possible value. Please find the snippets I tried.



if [[ "$TYPE" != "LOCAL" || "$TYPE" != "REMOTE" || "$TYPE" != "BOTH" ]]; then
echo -e "ntINCORRECT OR NULL ARGUMENTS PASSED. PLEASE VERIFY AND CORRECT THE USAGE MENTIONED AS BELOW: n"
Usage
exit 1
fi


if [[ "$TYPE" != "LOCAL" ]] || [["$TYPE" != "REMOTE" ]] || [["$TYPE" != "BOTH" ]]; then
echo -e "ntINCORRECT OR NULL ARGUMENTS PASSED. PLEASE VERIFY AND CORRECT THE USAGE MENTIONED AS BELOW: n"
Usage
exit 1
fi






share|improve this question













marked as duplicate by Jesse_b, schily, G-Man, slm♦ shell-script
Users with the  shell-script badge can single-handedly close shell-script questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Jul 27 at 17:26


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.










  • 4




    you want && not ||
    – RoVo
    Jul 27 at 12:54











  • @RoVo I want OR because $TYPE has 3 possible values viz. LOCAL,REMOTE or BOTH and if doesn't matches with any of these 3 then it should throw error. Your suggestion please.
    – Mahendra
    Jul 27 at 12:58







  • 2




    TYPE cannot simultaneously be equal to LOCAL, REMOTE, and BOTH. In plain English, your use of OR says "If type is not local, OR if type is not remote, OR if type is not both, throw an error." What you probably want is "If type is not local, AND is not remote, AND is not both, then throw an error." See the difference?
    – Kevin Kruse
    Jul 27 at 13:08












up vote
-1
down vote

favorite









up vote
-1
down vote

favorite












This question already has an answer here:



  • Using the not equal operator for string comparison

    6 answers



I am trying to compare the string stored in a variable with three different strings and if none of them match then throw an error. I've tried to do this in a single if statement using the logical operator OR. But every time I am getting error even though the value stored in the variable is same as one of the possible value. Please find the snippets I tried.



if [[ "$TYPE" != "LOCAL" || "$TYPE" != "REMOTE" || "$TYPE" != "BOTH" ]]; then
echo -e "ntINCORRECT OR NULL ARGUMENTS PASSED. PLEASE VERIFY AND CORRECT THE USAGE MENTIONED AS BELOW: n"
Usage
exit 1
fi


if [[ "$TYPE" != "LOCAL" ]] || [["$TYPE" != "REMOTE" ]] || [["$TYPE" != "BOTH" ]]; then
echo -e "ntINCORRECT OR NULL ARGUMENTS PASSED. PLEASE VERIFY AND CORRECT THE USAGE MENTIONED AS BELOW: n"
Usage
exit 1
fi






share|improve this question














This question already has an answer here:



  • Using the not equal operator for string comparison

    6 answers



I am trying to compare the string stored in a variable with three different strings and if none of them match then throw an error. I've tried to do this in a single if statement using the logical operator OR. But every time I am getting error even though the value stored in the variable is same as one of the possible value. Please find the snippets I tried.



if [[ "$TYPE" != "LOCAL" || "$TYPE" != "REMOTE" || "$TYPE" != "BOTH" ]]; then
echo -e "ntINCORRECT OR NULL ARGUMENTS PASSED. PLEASE VERIFY AND CORRECT THE USAGE MENTIONED AS BELOW: n"
Usage
exit 1
fi


if [[ "$TYPE" != "LOCAL" ]] || [["$TYPE" != "REMOTE" ]] || [["$TYPE" != "BOTH" ]]; then
echo -e "ntINCORRECT OR NULL ARGUMENTS PASSED. PLEASE VERIFY AND CORRECT THE USAGE MENTIONED AS BELOW: n"
Usage
exit 1
fi




This question already has an answer here:



  • Using the not equal operator for string comparison

    6 answers









share|improve this question












share|improve this question




share|improve this question








edited Jul 27 at 13:05









Kevin Kruse

17210




17210









asked Jul 27 at 12:42









Mahendra

34




34




marked as duplicate by Jesse_b, schily, G-Man, slm♦ shell-script
Users with the  shell-script badge can single-handedly close shell-script questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Jul 27 at 17:26


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by Jesse_b, schily, G-Man, slm♦ shell-script
Users with the  shell-script badge can single-handedly close shell-script questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
Jul 27 at 17:26


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









  • 4




    you want && not ||
    – RoVo
    Jul 27 at 12:54











  • @RoVo I want OR because $TYPE has 3 possible values viz. LOCAL,REMOTE or BOTH and if doesn't matches with any of these 3 then it should throw error. Your suggestion please.
    – Mahendra
    Jul 27 at 12:58







  • 2




    TYPE cannot simultaneously be equal to LOCAL, REMOTE, and BOTH. In plain English, your use of OR says "If type is not local, OR if type is not remote, OR if type is not both, throw an error." What you probably want is "If type is not local, AND is not remote, AND is not both, then throw an error." See the difference?
    – Kevin Kruse
    Jul 27 at 13:08












  • 4




    you want && not ||
    – RoVo
    Jul 27 at 12:54











  • @RoVo I want OR because $TYPE has 3 possible values viz. LOCAL,REMOTE or BOTH and if doesn't matches with any of these 3 then it should throw error. Your suggestion please.
    – Mahendra
    Jul 27 at 12:58







  • 2




    TYPE cannot simultaneously be equal to LOCAL, REMOTE, and BOTH. In plain English, your use of OR says "If type is not local, OR if type is not remote, OR if type is not both, throw an error." What you probably want is "If type is not local, AND is not remote, AND is not both, then throw an error." See the difference?
    – Kevin Kruse
    Jul 27 at 13:08







4




4




you want && not ||
– RoVo
Jul 27 at 12:54





you want && not ||
– RoVo
Jul 27 at 12:54













@RoVo I want OR because $TYPE has 3 possible values viz. LOCAL,REMOTE or BOTH and if doesn't matches with any of these 3 then it should throw error. Your suggestion please.
– Mahendra
Jul 27 at 12:58





@RoVo I want OR because $TYPE has 3 possible values viz. LOCAL,REMOTE or BOTH and if doesn't matches with any of these 3 then it should throw error. Your suggestion please.
– Mahendra
Jul 27 at 12:58





2




2




TYPE cannot simultaneously be equal to LOCAL, REMOTE, and BOTH. In plain English, your use of OR says "If type is not local, OR if type is not remote, OR if type is not both, throw an error." What you probably want is "If type is not local, AND is not remote, AND is not both, then throw an error." See the difference?
– Kevin Kruse
Jul 27 at 13:08




TYPE cannot simultaneously be equal to LOCAL, REMOTE, and BOTH. In plain English, your use of OR says "If type is not local, OR if type is not remote, OR if type is not both, throw an error." What you probably want is "If type is not local, AND is not remote, AND is not both, then throw an error." See the difference?
– Kevin Kruse
Jul 27 at 13:08










2 Answers
2






active

oldest

votes

















up vote
5
down vote



accepted










You've got your logic backward. Any string is guaranteed to be either different from LOCAL or different from REMOTE because a string cannot be LOCAL and REMOTE at the same time.



Here, the right tool for the task is a case statement (which is standard sh syntax contrary to those [[...]] ksh operators):



case $TYPE in
(REMOTE|LOCAL|BOTH) ;; # OK
(*) printf >&2 'Error...n'; exit 1;;
esac


If you wanted to use [[, in ksh or bash or zsh in ksh emulation you could do:



if [[ $TYPE != @(REMOTE|LOCAL|BOTH) ]]; then
printf >&2 'Error...n'
exit 1
fi


Or [[ $TYPE != REMOTE && $TYPE != LOCAL && $TYPE != BOTH ]] or [[ ! ($TYPE = REMOTE || $TYPE = LOCAL || $TYPE = BOTH) ]], etc.



Or using the standard [ command: [ "$TYPE" != REMOTE ] && [ "$TYPE" != LOCAL ] && [ "$TYPE" != BOTH ].



With ksh93, bash or zsh, another option is to use an associative array:



typeset -A allowed_TYPE
allowed_TYPE=([REMOTE]=1 [LOCAL]=1 [BOTH]=1)
if ((!allowed_TYPE[$TYPE])); then
printf >&2 'Error...n'
exit 1
fi


With zsh, you can also use a plain array:



 allowed_TYPE=(REMOTE LOCAL BOTH)
if ((! $allowed_TYPE[(Ie)$TYPE]))...





share|improve this answer






























    up vote
    -1
    down vote













    [updated]



    maybe not the cleanest method, but it works.



    declare an array variable and loop through it using awk to count the number of types that match in the declared array :



    declare -a a=("LOCAL" "REMOTE" "BOTH")
    types=$(echo $a[@] | wc -w)
    val=$(echo $a[@] | awk -v TYPE="$TYPE" 'split($0,a," ");for (key in a) if (a[key] != TYPE) print "#"' | wc -l)
    if [ $val -eq $types ]; then # if 0 matches
    echo "error"; exit 1;
    fi


    thanks to Stéphane Chazelas for pointing out the flaw in my previous answer.






    share|improve this answer























    • @StéphaneChazelas I have updated my answer to make it work, can you please have a look?
      – thatgeeman
      Jul 27 at 14:30

















    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    5
    down vote



    accepted










    You've got your logic backward. Any string is guaranteed to be either different from LOCAL or different from REMOTE because a string cannot be LOCAL and REMOTE at the same time.



    Here, the right tool for the task is a case statement (which is standard sh syntax contrary to those [[...]] ksh operators):



    case $TYPE in
    (REMOTE|LOCAL|BOTH) ;; # OK
    (*) printf >&2 'Error...n'; exit 1;;
    esac


    If you wanted to use [[, in ksh or bash or zsh in ksh emulation you could do:



    if [[ $TYPE != @(REMOTE|LOCAL|BOTH) ]]; then
    printf >&2 'Error...n'
    exit 1
    fi


    Or [[ $TYPE != REMOTE && $TYPE != LOCAL && $TYPE != BOTH ]] or [[ ! ($TYPE = REMOTE || $TYPE = LOCAL || $TYPE = BOTH) ]], etc.



    Or using the standard [ command: [ "$TYPE" != REMOTE ] && [ "$TYPE" != LOCAL ] && [ "$TYPE" != BOTH ].



    With ksh93, bash or zsh, another option is to use an associative array:



    typeset -A allowed_TYPE
    allowed_TYPE=([REMOTE]=1 [LOCAL]=1 [BOTH]=1)
    if ((!allowed_TYPE[$TYPE])); then
    printf >&2 'Error...n'
    exit 1
    fi


    With zsh, you can also use a plain array:



     allowed_TYPE=(REMOTE LOCAL BOTH)
    if ((! $allowed_TYPE[(Ie)$TYPE]))...





    share|improve this answer



























      up vote
      5
      down vote



      accepted










      You've got your logic backward. Any string is guaranteed to be either different from LOCAL or different from REMOTE because a string cannot be LOCAL and REMOTE at the same time.



      Here, the right tool for the task is a case statement (which is standard sh syntax contrary to those [[...]] ksh operators):



      case $TYPE in
      (REMOTE|LOCAL|BOTH) ;; # OK
      (*) printf >&2 'Error...n'; exit 1;;
      esac


      If you wanted to use [[, in ksh or bash or zsh in ksh emulation you could do:



      if [[ $TYPE != @(REMOTE|LOCAL|BOTH) ]]; then
      printf >&2 'Error...n'
      exit 1
      fi


      Or [[ $TYPE != REMOTE && $TYPE != LOCAL && $TYPE != BOTH ]] or [[ ! ($TYPE = REMOTE || $TYPE = LOCAL || $TYPE = BOTH) ]], etc.



      Or using the standard [ command: [ "$TYPE" != REMOTE ] && [ "$TYPE" != LOCAL ] && [ "$TYPE" != BOTH ].



      With ksh93, bash or zsh, another option is to use an associative array:



      typeset -A allowed_TYPE
      allowed_TYPE=([REMOTE]=1 [LOCAL]=1 [BOTH]=1)
      if ((!allowed_TYPE[$TYPE])); then
      printf >&2 'Error...n'
      exit 1
      fi


      With zsh, you can also use a plain array:



       allowed_TYPE=(REMOTE LOCAL BOTH)
      if ((! $allowed_TYPE[(Ie)$TYPE]))...





      share|improve this answer

























        up vote
        5
        down vote



        accepted







        up vote
        5
        down vote



        accepted






        You've got your logic backward. Any string is guaranteed to be either different from LOCAL or different from REMOTE because a string cannot be LOCAL and REMOTE at the same time.



        Here, the right tool for the task is a case statement (which is standard sh syntax contrary to those [[...]] ksh operators):



        case $TYPE in
        (REMOTE|LOCAL|BOTH) ;; # OK
        (*) printf >&2 'Error...n'; exit 1;;
        esac


        If you wanted to use [[, in ksh or bash or zsh in ksh emulation you could do:



        if [[ $TYPE != @(REMOTE|LOCAL|BOTH) ]]; then
        printf >&2 'Error...n'
        exit 1
        fi


        Or [[ $TYPE != REMOTE && $TYPE != LOCAL && $TYPE != BOTH ]] or [[ ! ($TYPE = REMOTE || $TYPE = LOCAL || $TYPE = BOTH) ]], etc.



        Or using the standard [ command: [ "$TYPE" != REMOTE ] && [ "$TYPE" != LOCAL ] && [ "$TYPE" != BOTH ].



        With ksh93, bash or zsh, another option is to use an associative array:



        typeset -A allowed_TYPE
        allowed_TYPE=([REMOTE]=1 [LOCAL]=1 [BOTH]=1)
        if ((!allowed_TYPE[$TYPE])); then
        printf >&2 'Error...n'
        exit 1
        fi


        With zsh, you can also use a plain array:



         allowed_TYPE=(REMOTE LOCAL BOTH)
        if ((! $allowed_TYPE[(Ie)$TYPE]))...





        share|improve this answer















        You've got your logic backward. Any string is guaranteed to be either different from LOCAL or different from REMOTE because a string cannot be LOCAL and REMOTE at the same time.



        Here, the right tool for the task is a case statement (which is standard sh syntax contrary to those [[...]] ksh operators):



        case $TYPE in
        (REMOTE|LOCAL|BOTH) ;; # OK
        (*) printf >&2 'Error...n'; exit 1;;
        esac


        If you wanted to use [[, in ksh or bash or zsh in ksh emulation you could do:



        if [[ $TYPE != @(REMOTE|LOCAL|BOTH) ]]; then
        printf >&2 'Error...n'
        exit 1
        fi


        Or [[ $TYPE != REMOTE && $TYPE != LOCAL && $TYPE != BOTH ]] or [[ ! ($TYPE = REMOTE || $TYPE = LOCAL || $TYPE = BOTH) ]], etc.



        Or using the standard [ command: [ "$TYPE" != REMOTE ] && [ "$TYPE" != LOCAL ] && [ "$TYPE" != BOTH ].



        With ksh93, bash or zsh, another option is to use an associative array:



        typeset -A allowed_TYPE
        allowed_TYPE=([REMOTE]=1 [LOCAL]=1 [BOTH]=1)
        if ((!allowed_TYPE[$TYPE])); then
        printf >&2 'Error...n'
        exit 1
        fi


        With zsh, you can also use a plain array:



         allowed_TYPE=(REMOTE LOCAL BOTH)
        if ((! $allowed_TYPE[(Ie)$TYPE]))...






        share|improve this answer















        share|improve this answer



        share|improve this answer








        edited Jul 27 at 13:43


























        answered Jul 27 at 13:31









        Stéphane Chazelas

        278k52512842




        278k52512842






















            up vote
            -1
            down vote













            [updated]



            maybe not the cleanest method, but it works.



            declare an array variable and loop through it using awk to count the number of types that match in the declared array :



            declare -a a=("LOCAL" "REMOTE" "BOTH")
            types=$(echo $a[@] | wc -w)
            val=$(echo $a[@] | awk -v TYPE="$TYPE" 'split($0,a," ");for (key in a) if (a[key] != TYPE) print "#"' | wc -l)
            if [ $val -eq $types ]; then # if 0 matches
            echo "error"; exit 1;
            fi


            thanks to Stéphane Chazelas for pointing out the flaw in my previous answer.






            share|improve this answer























            • @StéphaneChazelas I have updated my answer to make it work, can you please have a look?
              – thatgeeman
              Jul 27 at 14:30














            up vote
            -1
            down vote













            [updated]



            maybe not the cleanest method, but it works.



            declare an array variable and loop through it using awk to count the number of types that match in the declared array :



            declare -a a=("LOCAL" "REMOTE" "BOTH")
            types=$(echo $a[@] | wc -w)
            val=$(echo $a[@] | awk -v TYPE="$TYPE" 'split($0,a," ");for (key in a) if (a[key] != TYPE) print "#"' | wc -l)
            if [ $val -eq $types ]; then # if 0 matches
            echo "error"; exit 1;
            fi


            thanks to Stéphane Chazelas for pointing out the flaw in my previous answer.






            share|improve this answer























            • @StéphaneChazelas I have updated my answer to make it work, can you please have a look?
              – thatgeeman
              Jul 27 at 14:30












            up vote
            -1
            down vote










            up vote
            -1
            down vote









            [updated]



            maybe not the cleanest method, but it works.



            declare an array variable and loop through it using awk to count the number of types that match in the declared array :



            declare -a a=("LOCAL" "REMOTE" "BOTH")
            types=$(echo $a[@] | wc -w)
            val=$(echo $a[@] | awk -v TYPE="$TYPE" 'split($0,a," ");for (key in a) if (a[key] != TYPE) print "#"' | wc -l)
            if [ $val -eq $types ]; then # if 0 matches
            echo "error"; exit 1;
            fi


            thanks to Stéphane Chazelas for pointing out the flaw in my previous answer.






            share|improve this answer















            [updated]



            maybe not the cleanest method, but it works.



            declare an array variable and loop through it using awk to count the number of types that match in the declared array :



            declare -a a=("LOCAL" "REMOTE" "BOTH")
            types=$(echo $a[@] | wc -w)
            val=$(echo $a[@] | awk -v TYPE="$TYPE" 'split($0,a," ");for (key in a) if (a[key] != TYPE) print "#"' | wc -l)
            if [ $val -eq $types ]; then # if 0 matches
            echo "error"; exit 1;
            fi


            thanks to Stéphane Chazelas for pointing out the flaw in my previous answer.







            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited Jul 27 at 14:27


























            answered Jul 27 at 13:16









            thatgeeman

            977




            977











            • @StéphaneChazelas I have updated my answer to make it work, can you please have a look?
              – thatgeeman
              Jul 27 at 14:30
















            • @StéphaneChazelas I have updated my answer to make it work, can you please have a look?
              – thatgeeman
              Jul 27 at 14:30















            @StéphaneChazelas I have updated my answer to make it work, can you please have a look?
            – thatgeeman
            Jul 27 at 14:30




            @StéphaneChazelas I have updated my answer to make it work, can you please have a look?
            – thatgeeman
            Jul 27 at 14:30


            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay