ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
In the simplest terms,. the || does not care about command1 at all. It only cares about command2.
This is incorrect in that the || cares about both command1 and command2. To use the existing example:
Code:
$ false && true || echo false
false
So it is still not like the if/else construct, because either of the first commands returning a false or non-zero value will cause command3 to execute.
Well, there’s no ternary operator in Bash, but there is a way to fake it.
Code:
valid=1
[ $valid ] && x=1 || x=0
Because the ternary operator is if then else but because BASH does not support it. Someone came up with that way for it to be "supported". Using brackets to test for true first,
this method is setup to check the first command for true, then to pick - if true then second command, if not true then third command as you use the term "command" to justify your statement.
whereas what you call the first command is not an actual command. it is a condition that is being tested to see if it is a true statement or not.
therefore, the command after the && is not included in the test of what you call the first command.
they are not being tested as if command1 is true and command2 is true then issue command3.
it is testing if [condition is true] && (then) command2 || (if not true or else) command3
that is the purpose of
Code:
[ test ] && true || false
it has nothing to do with exit codes where
if exit = zero it is true because of no errors
if exit = non zero it is false because of errors
it has to do with what you are checking for is equates to a 'true' or 'not true'
if you are looking for errors then this is how you would write it.
Code:
if [ condition=0 ] then true else false fi
[ if non zero ] && true || false
[ if zero ] && true || false
the [ test (command1) ] looks for a truth to be had regardless if it is a zero or non zero to issue the next command2 else issue the other command3
the way you are writing it you are mixing up your logic to try and prove your point.
the statment before the && is being tested to see if it is a true statement. if it is then the command right after && will be issued, if it equates to a false then the command right after || will be issued.
all you are doing is trying to say a true is a lie regardless in your second example by how you have written it. Which the program is still working because it is doing what you told it to by obeying your commands.
if true then lie else lie fi
true && lie || lie
your second example out puts lie no matter if it is a truth or not because it has no choice to do other wise.
it looks to me that all three of you are thinking in error.
In a real IF/THEN statement you would write some code after THEN correct? If that code failed you would NOT expect the ELSE section to fire off.
If you write some code after the && statement and that code failed the || section WILL fire off.
Thats a huge DIFFERENCE in logic. Its not a true IF THEN ELSE test. Its a left->right precedence testing for exit codes.
Here is the section in the Bash manual - notice it mentions EXIT CODES and not TRUE/FALSE Boolean logic.
Quote:
Lists
A list is a sequence of one or more pipelines separated by one of the operators ;, &, &&, or ||, and optionally terminated by one of ;, &, or <newline>.
Of these list operators, && and || have equal precedence, followed by ; and &, which have equal precedence.
A sequence of one or more newlines may appear in a list instead of a semicolon to delimit commands.
If a command is terminated by the control operator &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0. Commands separated by a ;
are executed sequentially; the shell waits for each command to terminate in turn. The return status is the exit status of the last command executed.
AND and OR lists are sequences of one of more pipelines separated by the && and || control operators, respectively. AND and OR lists are executed with left associativity. An AND list has the form
command1 && command2
command2 is executed if, and only if, command1 returns an exit status of zero.
An OR list has the form
command1 || command2
command2 is executed if and only if command1 returns a non-zero exit status. The return status of AND and OR lists is the exit status of the last command executed in the list.
Last edited by szboardstretcher; 01-18-2017 at 09:40 AM.
AND and OR lists are sequences of one of more pipelines
separated by the && and || control operators, respectively.
AND and OR lists are executed with left associativity.
An AND list has the form
command1 && command2
command2 is executed if, and only if, command1 returns an exit
status of zero.
command2 is executed if, and only if, command1 returns an exit status of zero.
which equates as a true
non zero is false
if true(zero) then command2 else command3
0 && true || false
boolean --
so I have mislead by what I said on zero and boolean on off yes no but it is still using the zero and any non zero for boolean.
it has to be a true first to get whatever is after && to be fired off || do that one instead.
if 0 then true else false
boolean
Code:
An OR list has the form
command1 || command2
command2 is executed if and only if command1 returns a non-zero
exit status. The return status of AND and OR lists is the exit
status of the last command executed in the list.
the opposite is true
it is still boolean but backwords
being that it is at the tail end of putting the two together it equates to a
if then else statment because of the condition it is checking for.
&& checks for zero
|| checks for non zero
putting them together you get
first command1 has to be a zero to get the second command to fire off
if it is a non zero or false then the || takes over and fires off that command
therefore again you are thinking in error. put the pieces together
command2 is executed if and only if command1 returns a non-zero
exit status.
separately
This is my final example. This is a classic if/then/else block in bash, even though the 'then' block fails, ELSE will not run.
Code:
if [ true ]; then
[ 1 == 22 ];
else
echo "ran the else block"
fi
Here is the same thing with && and ||. When you run these do you notice a difference? Its not Lying to the || operator. Its evaluating a test that happens to fail then running an ELSE block. That is not how a ternary operator in C works.
This is my final example. This is a classic if/then/else block in bash, even though the 'then' block fails, ELSE will not run.
Code:
if [ true ]; then
[ 1 == 22 ];
else
echo "ran the else block"
fi
Here is the same thing with && and ||. When you run these do you notice a difference? Its not Lying to the || operator. Its evaluating a test that happens to fail then running an ELSE block. That is not how a ternary operator in C works.
This is my final example. This is a classic if/then/else block in bash, even though the 'then' block fails, ELSE will not run.
Code:
if [ true ]; then
[ 1 == 22 ];
else
echo "ran the else block"
fi
Here is the same thing with && and ||. When you run these do you notice a difference? Its not Lying to the || operator. Its evaluating a test that happens to fail then running an ELSE block. That is not how a ternary operator in C works.
My argument is simply that IF/THEN/ELSE is not the same as && || as seen here.
you changing the equation !
stop!
the brackets do what?
you are checking conditions with the brackets whereas the equation is written like this
[ test for zero ] && zero || not zero
[true] && yes || no
as per your bash documentation you showed me but have no understanding of nor it seems the virtue of humility. you @szboardstretcher are not putting the pieces of the puzzle together right you are cheating to try and prove to me you are a truth when you are not.
by changing the truth into a lie then presenting it as a truth.
it is not written
Code:
if [ true ]; then
[ 1 == 22 ];
else
echo "ran the else block"
that is a lie!
it is written
Code:
if [true] ; then
do someting
else
do something else
fi
I would like to point out something .... '[' is a command as it is a synonym for the 'test' command. You are correct that it evaluates the contents between '[]', but after doing so it then returns
an exit status of its own, namely zero if the expression evaluates to true and non-zero otherwise.
As pointed out by szboardstretcher, you would not expect either a true ternary operator or an if/then/else construct to return the last or else value after the first or if/then part were executed,
hence, the && and || construct is not a ternary operation but it can appear that way given the right circumstances.
As szboardstretcher has demonstrated the if/then/else aspect, the flipside is where bash does use the ternary operator:
Code:
x=1
(( y = x == 1 ? 2 : 3 ))
echo $y
(( y = x > 1 ? 2 : 3 ))
echo $y
In the examples above, 'y' will only ever be set to one value depending on the expression tested, it will NEVER be set to '2' temprarily and then set to '3'.
This is definitely false. Logical operators work on the exit code of the commands and checks if the exit code was equal to 0 or not. exitcode = 0 means ok, exitcode != 0 means error (or not ok).
So you need to read:
Code:
if command1 then command2 else command3
# execute command1 and if the returncode was 0 execute command2 else (= returncode was nonzero) execute command3
the other construction:
Code:
[ command1 ] && command2 || command3
# actually [ ] is not required at all. You should read it from left to right and you can also imagine there is a () - but that is syntactically not correct:
command1 && command2 || command3
# or:
( command1 && command2 ) || command3
# meaning: if command1 returned ok AND command2 returned ok the expression inside () will be ok, so || means command3 should not be executed
if either command1 or command2 returned notok, () will be false - or not ok, therefore || will execute command3
read the man page of bash about that, the execution of the right side (of || and && ) depends on the left side, if that was enough to find out the result the right side will be skipped, if the left side will not give enough information to decide, right side will be executed too. That is definitely different logic, not similar to if/then/else.
I would like to point out something .... '[' is a command as it is a synonym for the 'test' command. You are correct that it evaluates the contents between '[]', but after doing so it then returns
an exit status of its own, namely zero if the expression evaluates to true and non-zero otherwise.
As pointed out by szboardstretcher, you would not expect either a true ternary operator or an if/then/else construct to return the last or else value after the first or if/then part were executed,
hence, the && and || construct is not a ternary operation but it can appear that way given the right circumstances.
As szboardstretcher has demonstrated the if/then/else aspect, the flipside is where bash does use the ternary operator:
Code:
x=1
(( y = x == 1 ? 2 : 3 ))
echo $y
(( y = x > 1 ? 2 : 3 ))
echo $y
In the examples above, 'y' will only ever be set to one value depending on the expression tested, it will NEVER be set to '2' temprarily and then set to '3'.
again @szboardstretcher uses a lie to try and prove a truth. Period!
by changing the equation to get a different answer.
As you and what I have read that BASH does not support ternary operation, but because of the && and || in what it acts on
&& acts on a return of zero
|| acts on a return of non zero
zero == true
non zero == false
[ ] test for what? a true or zero from what I am finding out.
if you put the two together then you can get your else results to also be issued in case of a non zero being returned.
therefore if written like this
[ test for zero return code ] && here it only acts on a zero || here it only acts on a non zero
NOT writing like @szboardstretcher wrote it to use a lie to prove a point.
[ test for return of zero ] && [test for return of zero again ] || do if non zero is gotten ( but from which test?)
that just throws everything off by @szboardstretcher non zero ways. That is why it is not working properly. Regardless by what you even said, "given the right circumstances"
by how @szboardstretcher is changing it so the right circumstances will NEVER take place for it to work no matter what.
why it seems you cannot see that is a matter of option.
now ets see what kind of person you are by pulling what you wrote apart and see what is really going on in that code you gave me now.
what is this really doing?
the first test you give me in your example is testing for what?
Code:
x=1
(( y = x == 1 ? 2 : 3 ))
echo $y
to see if y and x equal 1 because you made them both equal one (1).
if they both equal 1 then the return code is zero therefore whatever is right after the && command will be issued. the results then will be 2 yes? YES!
which it is if one was to put that into a bash file and run it. therefore a true was give because Y = 1 it is a truth.
Now Mr. who do you say you are? the truth? really? lets take a look at this other one that you are trying to use to prove me a liar.
Code:
(( y = x > 1 ? 2 : 3 ))
echo $y
what is this one doing? looking to see if y which equals x which is 1 is greater then itself which is 1. we all should know that 1 is not greater then 1 it is equal to 1.
therefore it returns what? a non zero because it is not a true statement the condition it is really checking for is here
to show what it is really doing it can be written like this.
Code:
y=1
(( y = x = 1 [ is x > 1 ] ? yes 2 : no 3 ))
if [ 1 is greater than 1 ] ; then
do this
else
do this
fi
the truth is that x is not greater then 1. it does not equate to a true statement that the test will always act on the command given if it is. therefore it returns a non zero.
the non zero uses what operators to act on?
---------> : or ||
therefore y = 3 because the || acts on a non zero
because you told it to. Not because it is a false statement. if it was a true statement then the ? or && would have fired off the command after it.
but because one cannot ever be greater then itself it will always return what?
that is just bad coding logic to test to see if something is greater then itself.
you are just like the other. You just tried to do it more deceivingly then @szboardstretcher by the way he wrote it.
because by the way you are writing it is just like he did
" changing it so the right circumstances will NEVER take place for it to work no matter what."
Not because because I am wrong but because birds of a feather flock together.
touch /tmp/myfile
chattr +i /tmp/myfile
[ -e /tmp/myfile ] && echo "text" > /tmp/myfile || echo "file does not exist"
-bash: /tmp/myfile: Permission denied
file does not exist
Supposed plain english:
If file exists, then echo text into it, else echo file does not exist.
Results:
You will notice that it echos 'file does not exists' even though the file clearly exists, because the second command failed - not the first. This is not IF/THEN/ELSE behavior.
Code:
if [ -e /tmp/myfile ]; then
echo "text" > /tmp/myfile
else
echo "file does not exist"
fi
-bash: /tmp/myfile: Permission denied
Plain english:
If file exists, then echo text into it, else echo file does not exist.
Results:
The file existed, so it attempted to echo text into it. Since the file existed, it did not echo 'file does not exist'. This is typical IF/THEN/ELSE behavior.
Last edited by szboardstretcher; 01-18-2017 at 11:46 AM.
I really would appreciate it if you would stop telling us that we are lying. The fact that we cannot get our point across to you does not make us liars, it simply means we have not found the correct way to express what we are trying to say in such a way that you can follow what we mean.
So I will try yet another way, please evaluate the following:
Code:
if touch file_name
then
rm file_name
rm file_name
else
stat file_name
fi
# Alternatively
touch file_name && { rm file_name; rm file_name; } || stat file_name
Please explain using your methods how these 2 expressions are the same? You can put both in a script and run them and you will find that the output is not the same, but according to your current logic
they should result in exactly the same output as would be the case when using if/then/else or the ternary operation in any other language.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.