LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 03-04-2020, 06:09 PM   #1
ziphem
Member
 
Registered: Feb 2004
Location: US / EU
Distribution: Fedora 31
Posts: 225

Rep: Reputation: 29
Two conditions in "if" statement: if first fails, does it check second condition?


I hope I don't embarrass myself with the question, and I presume the answer, but wanted to verify. I tried to look this up on Google, but wasn't sure how to properly describe it, and so couldn't find anything that gave an answer on it.

Question: when there are two conditions in an if / then statement with certain required matches, and the first match is not met, does the script then make a conclusion at that point? Or does it always check both conditions regardless?

So, for example:

Code:
if [ "$item1" = 'A' ] && [ "$item2" = 'B' ]; then
    echo "Success"
else
    echo "Fail"
fi
and $item1 does not equal A, does the script stop without checking the other condition and put me to "else"? Or will it always check the second condition [ "$item2" = 'B' ]?

Maybe more detail than anyone wants, but my reason: $item1 = From my computer, I want to check whether my phone is connected to the network - and this can be any network:
Code:
 nmap -T4 -A -v -oG - `/sbin/ip -o -4 addr list ***MY WIRELESS DEVICE*** |  awk '{print $4}' | cut -d/ -f1 | grep -Po '.*(?=\.)'`.USUAL PORT RANGE -Pn -p PORT NUMBER WHERE PHONE WILL LISTEN | grep 'MY PHONE NAME' | grep -Pom 1 '[0-9.]{7,15}' | sort -u
$item 2 = If it is, I verify with a test SSH. If $item1 fails, I don't want to send a test login to some random IP address on the network. For reference that test login:
Code:
sshpass -p 'PASSWORD' ssh $PHONE -p PHONE'S SSH PORT -o ConnectTimeout=10 'exit 0' 2>&1 | grep 'TEXT OUTPUT WHEN SSHED IN'
(I have a bunch of other protections in place - I only turn on my phone's Wifi and SSH server, check if I'm on a non-standard IP, check if on VPN, etc. etc. My script works now, just trying to clean up and simplify. I'll probably post the final code in case it benefits someone else.)

Thanks a ton!

Last edited by ziphem; 03-04-2020 at 06:10 PM.
 
Old 03-04-2020, 06:40 PM   #2
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206
Quote:
Originally Posted by ziphem View Post
Question: when there are two conditions in an if / then statement with certain required matches, and the first match is not met, does the script then make a conclusion at that point?
Yes, if the first condition fails it is done...
 
2 members found this post helpful.
Old 03-04-2020, 06:44 PM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,783

Rep: Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936Reputation: 5936
Furthermore, an if statements evaluates to either true or false and multiple conditions follows binary math i.e.
Code:
false && false = false
true  && false = false
false && true  = false
true  && true  = true
if both are true then echo success otherwise echo fail.
 
3 members found this post helpful.
Old 03-04-2020, 11:44 PM   #4
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218
After the if normal shell code follows until it reaches a then, at that point the $? (last exit status) decides if the following normal shell code up to a fi or else is run.
The following demonstrates it (I hope)
Code:
if
    echo "now running test command(s)"
    [ "$item1" = 'A' ] && [ "$item2" = 'B' ]
then
    echo "Success"
else
    echo "Fail"
fi
So, the question is about normal shell code rather than a specific if-then behavior.
Indeed && and || are logical operators.
If the $? is not 0 (false) then a && command is skipped.
If the $? is 0 (true) then a || command is skipped.
 
1 members found this post helpful.
Old 03-04-2020, 11:48 PM   #5
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218
After the if normal shell code follows until it reaches a related then, at that point the $? (last exit status) decides if the following normal shell code up to a related fi or else is run.
The following demonstrates it (I hope)
Code:
if
    echo "now running test command(s)"
    [ "$item1" = 'A' ] && [ "$item2" = 'B' ]
then
    echo "Success"
else
    echo "Fail"
fi
So, the question is about normal shell code rather than a specific if-then behavior.
Indeed && and || are logical operators.
If the $? is not 0 (false) then a && command is skipped.
If the $? is 0 (true) then a || command is skipped.

Note the "inverse" values for true and false, this is specific to the shell.
Other programming languages have non-0 for true and 0 for false

Last edited by MadeInGermany; 03-04-2020 at 11:57 PM.
 
1 members found this post helpful.
Old 03-05-2020, 03:29 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,037

Rep: Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345
with other words: the conditional expression will be evaluated, and if the result was found the evaluation is stopped.
Code:
if [[ conditionA ]] && [[ conditionB ]]
if conditionA is false, the result will be false anyway (regardless of conditionB), so the second part will not be evaluated.

You can simply check how does it work:
Code:
{ echo 1; false; } || { echo 2; false; } && { echo 3; true; }
 
Old 03-07-2020, 12:09 PM   #7
themanwhowas
Member
 
Registered: Nov 2005
Distribution: CentOS 5, Fedora 23
Posts: 218

Rep: Reputation: 29
&& is a conditional and or a short circuit and. The 2nd part will not be evaluated if the first fails.

Using & instead of && will evaluate both parts.
Code:
a = 0;
if(a!=0 && b%a)
will work fine as if a !=0 the second test won't run. If however you have
Code:
a = 0;
if(a!=0 & b%a)
you will get a divide by zero.

Same with or ||
 
Old 12-06-2023, 09:35 PM   #8
ziphem
Member
 
Registered: Feb 2004
Location: US / EU
Distribution: Fedora 31
Posts: 225

Original Poster
Rep: Reputation: 29
Guys, I never did say - thank you for the feedback! It was helpful. I appreciate it.
 
Old 12-07-2023, 02:34 AM   #9
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,269
Blog Entries: 24

Rep: Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206Reputation: 4206
Quote:
Originally Posted by ziphem View Post
Guys, I never did say - thank you for the feedback! It was helpful. I appreciate it.
You are welcome! We appreciate the return and feedback!
 
Old 12-07-2023, 02:45 AM   #10
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,356
Blog Entries: 3

Rep: Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767Reputation: 3767
Quote:
Originally Posted by ziphem View Post
If $item1 fails, I don't want to send a test login to some random IP address on the network.
Speaking of feedback, in that case you really ought to use an SSH key for authentication instead of sending out passwords for harvesting if you somehow manage to contact the wrong server. The key can be locked down on the server end so that it does nothing:

Code:
command="true" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHjK/gl+HLaqkwoUCxksnqueQmETAz6GwSMYsQD36VV6 network test
Then it will return success but disconnect immediately if it gets through.
 
Old 12-07-2023, 03:25 AM   #11
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
I didn't see it mentioned above, but just to add a little for anyone returning to this thread...

This will check for the existence of both files, even if the first doesn't exist:
if [ -f file1 -a -f file2 ] ...

These won't:
if [ -f file1 ] && [ -f file2 ] ...
if [[ -f file1 && -f file2 ]] ...



For this reason most shell-scripting "style guides" will advise you not to use the '-a' option in a 'test'.
 
2 members found this post helpful.
Old 12-07-2023, 05:12 AM   #12
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218Reputation: 1218
And you can prove it with
Code:
$ strace -f sh -c '[ -f file1 -a -f file2 ]' 2>&1 | grep -w 'file[12]'
execve("/bin/sh", ["sh", "-c", "[ -f file1 -a -f file2 ]"], 0x3fffdff618 /* 23 vars */) = 0
newfstatat(AT_FDCWD, "file1", 0x3fffa79d78, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "file2", 0x3fffa79d68, 0) = -1 ENOENT (No such file or directory)

$ strace -f sh -c '[ -f file1 ] && [ -f file2 ]' 2>&1 | grep -w 'file[12]'
execve("/bin/sh", ["sh", "-c", "[ -f file1 ] && [ -f file2 ]"], 0x3fffbee618 /* 23 vars */) = 0
newfstatat(AT_FDCWD, "file1", 0x3fffd09c48, 0) = -1 ENOENT (No such file or directory)

$ strace -f bash -c '[[ -f file1 && -f file2 ]]' 2>&1 | grep -w 'file[12]'
execve("/bin/bash", ["bash", "-c", "[[ -f file1 && -f file2 ]]"], 0x3ffffc1618 /* 23 vars */) = 0
newfstatat(AT_FDCWD, "file1", 0x3fffe21f18, 0) = -1 ENOENT (No such file or directory)

$

Last edited by MadeInGermany; 12-07-2023 at 05:14 AM.
 
2 members found this post helpful.
Old 12-07-2023, 08:00 AM   #13
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,688
Blog Entries: 4

Rep: Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947
The official name for this idea is "short-circuit" expression evaluation – routinely used for if statements and other conditionals. As soon as it can be determined that the branch will or will not be taken, further evaluation is not performed. This very expressive notion is used a lot, because it makes "clean" code.

Contrast this to bitwise evaluation within, say, an assignment statement.

Last edited by sundialsvcs; 12-07-2023 at 08:02 AM.
 
Old 12-08-2023, 12:07 AM   #14
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,037

Rep: Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345Reputation: 7345
Quote:
Originally Posted by sundialsvcs View Post
The official name for this idea is "short-circuit" expression evaluation – routinely used for if statements and other conditionals. As soon as it can be determined that the branch will or will not be taken, further evaluation is not performed. This very expressive notion is used a lot, because it makes "clean" code.
The problem is that many people don't know about it, so they don't use it properly (that's why we have this thread too).
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
conditions with if else statement malinl87 Linux - Newbie 11 10-27-2019 03:03 PM
syntax for two different conditions in if statement vjlxmi Linux - Newbie 5 08-27-2014 10:12 AM
check Negative egrep condition in an if condition novicunix Programming 5 02-02-2013 12:52 AM
[SOLVED] Split a file into two - the first being the first two lines and the second the rest jasonws Linux - General 2 11-02-2010 04:32 AM
using OR condition in if condition Fond_of_Opensource Linux - Newbie 2 10-20-2006 12:34 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 09:05 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration