Files

219 lines
13 KiB
Plaintext
Raw Permalink Normal View History

Episode: 3713
Title: HPR3713: Bash snippet - short-circuit evaluation in Bash Boolean expressions
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr3713/hpr3713.mp3
Transcribed: 2025-10-25 04:30:58
---
This is Hacker Public Radio Episode 3,713 for Wednesday, the 26th of October 2022.
Today's show is entitled, Bash Snippet Short Circuit Evaluation in Bash Boolean Expressions.
It is part of the series, Bash Scripting.
It is hosted by Dave Morris and is about 17 minutes long.
It carries an explicit flag.
The summary is, found I could do this in Bash, so wanted to share.
Hello everybody, welcome to Hacker Public Radio.
My name is Dave Morris and today I'm doing a show on Bash.
So the show is entitled, a Bash Snippet.
And it talks about, well I talk about, short circuit evaluation in Bash Boolean Expressions.
This is something that I came upon using Bash recently.
Never considered it before because on the whole I don't think of Bash as a programming language,
though it's actually a lot more powerful than I thought in the past.
I was surprised to find that there was a way of doing a thing that I would have known
how to do in other programming languages, but didn't know how to do in Bash.
Now this may be entirely and completely obvious to you that this is a feature and so on.
And if so, well I'm sorry.
You might hang around or head off and do something else, up to you.
To start by giving you an overview of what it is I'm talking about,
most programming language or many anyway have the concept of short circuit evaluation
in Boolean Expressions.
And what this means is that if you have an expression in whatever context,
Boolean expression which is written like A and B.
I've used A and B as the example here in the notes and I've used the word A and D,
but there's different ways of expressing it in different languages.
So in this A and B case, if A is false, then the whole expression must be false.
B doesn't have to be evaluated.
That's because both arguments to AND have to be true, the overall result to be true.
So false and true or false and false return false.
Any false in an expression using AND results in a false outcome.
So if A is true in this example, then we don't yet know
what the overall expression is true or false. So we have to evaluate B in order to see
if the overall result is true.
There's a similar case with using the OR keyword, whatever variant you have,
A or B. If A is true, then the whole expression must be true and B can be skipped
without evaluation. This is because only one argument to OR needs to be true
to return a true result. If A is false on the other hand, then B has to be evaluated
to determine if the overall result is false.
Because any one true in a pair of expressions separated by an OR will return true.
So I was looking for a definition of this thing.
The definition that I came up with was that in simple terms short circuiting
is where evaluation of an expression is stopped as soon as its outcome is determined.
So that's pretty much what I've tried to explain in the overview.
There's a lot more detailed explanations if you go hunting for them.
The one in the Wikipedia article short circuit evaluation
defines it as short circuit evaluation, minimal evaluation or McCarthy evaluation
after John McCarthy is the semantics of some Boolean operators in some programming languages
in which the second argument he executed or evaluated only if the first argument
does not suffice to determine the value of the expression.
When the first argument of the AND function evaluates to false, the overall value must be false.
When the first argument of the OR function evaluates to true, the overall value must be true.
Now in this article, which is fairly heavy going, but you might like to have looked at it.
There's a table entitled Boolean operators in various languages which shows details
of how various programming and scripting languages cater for this feature.
So what was my use case? Why did I want to get into this stuff?
I was writing a bash script in which I wanted to ask questions about various steps
should they be done or not. Alternatively, I wanted to be able to set an option
to run without interaction and assume the answer is yes to all questions.
You've probably seen commands where you can just give them hyphen yes or some such thing
which means don't ask me just to assume yes.
So I'd encountered short circuit evaluation before.
I was a Pascal programmer for several years on VMS system.
And that had...
Actually, the short circuit stuff was added into a later iteration of Pascal.
Interestingly enough.
And I've used Poe as long probably
and that offers short circuit evaluation.
I wondered if a bash would allow me to do it.
I hadn't seen anything explicit about it.
But then if you looked at the bash man pages, then it's incredibly dense.
So I still haven't looked to see if I could find anything there.
Probably it was there and I missed it.
Anyway, the expression I was trying to write was an if statement in bash, which was if.
And then that's followed by two open square brackets, which is one of the test formats
that you have in a modern bash.
Then dollar yes, the variable yes, hyphen equals one.
And then close the two square brackets.
Then an or statement or function, how do you call that?
Which is two vertical bars.
Then a call to a bash function yes, underscore no, where it's got various parameters
which I won't bother with.
They're in the notes.
Then after that, semicolon then.
And the body of the if would create the directory.
And then that's close with an f i for the end of the if.
So the variable yes is being set through an option in this script, which is the hyphen y option.
It's normally set to zero, which means false in this script.
But it's set to one if the option is used.
And yes, knows a function that I wrote some years ago.
And I actually did an HBR episode about it.
Useful bash functions episode 2096.
So the requirement was that if yes was set to one, I didn't want the function to be called at all.
But having written this and tried it was surprised.
It's very happy to find that that's exactly what happens.
So I've included the longer, a longer snippet out of the script.
It's quite a large script and it's to do with my managing incoming show notes for shows
that have been sent to HBR.
I want necessarily read all this, because it's quite a lot to read.
But there's a test to see if a directory exists, which is in the name of which is in the variable showeder.
If it doesn't exist, then a message is output saying that there's no directory.
And then we either want to ask the question, do we want to create this directory?
To reach the answer, it normally would be yes anyway, but it's useful just to...
I thought it was useful to have this ability to ask.
But if the yes variable is set to one, as I just explained,
then ignore the yes, no business and just make the directory.
It just isn't a side.
You will see references to dollar, open curly bracket, green, close curly bracket, and various other colors.
And that's the result of running a bash function I wrote, which defines colors,
which has been included in this script from a library of functions.
So things like echo, open, double quotes, dollar, open brace, read, then some text,
dollar, open brace, reset, close brace, close, double quotes.
Stuff like that means I put this string in in red.
I do have another function which just turns off all of these color control codes
by changing the variables to empty strings.
So the yes, no function, which I have documented a little bit here,
takes a prompt string with an optional percent s in it,
and it takes a default answer.
So you're going to either give it yes or no, I think.
And in this case, we've got knows the default.
So the prompt will produce a string in it that's got yes and no,
with the default in capitals and the other in lowercase.
Then the other thing in this code is that I call a function called underscore silent.
And that's simply a way in which I can control whether messages get written or not,
it's useful to be able to run this thing in a silent way by calling up from another script.
So if the silent variable is set to one in the script,
which is done through an option, then it keeps quiet.
So the question then, should you be using short circuiting?
Well, we've got two cases here which I'll try and discuss this in a little bit of detail.
The bash actually uses short circuiting in other contexts.
And we've looked at it, if you've been following my bash tips series,
episode 10, covered it.
And the example given was using another version of the test capability,
which is single square brackets around an expression.
And in this case, it's hyphen E, which means a file exists,
followed by the name of a file, so the closed square bracket,
and then two vertical bars, which is OR, and then exit space 1.
So the test here is to check to see if the file exists,
and the results are the true or false.
If the test returns true, then the overall result of the OR expression is true.
And the evaluation is short circuited, so that the exit 1,
which is not a logical test, its merely command, is not invoked.
If the test is false, then the second expression has to be evaluated
to determine the overall result.
So the exit 1 is invoked, and the script exits.
So that's a sort of a cheat, but it's part of the way that bash works.
And I mentioned here that the square brackets hyphen E file construct
is actually an instance of the test command, which I did mention in that previous show,
but I've written out what it would look like if you used the test command.
You might be familiar with command pipelines, which use this sort of technique,
and it was certainly mentioned in that previous show,
which is going back a few years, by the way.
So the thing that you might write, if you're a debbie or a bunch of user,
are probably less so these days.
You might be used to typing pseudo apt update, ampusand ampusand pseudo apt upgrade,
which means do the update, and if that works, do the upgrade.
So yeah, as I've written here, if the apt update is successful,
the apt upgrade is run.
If it fails, the second command is not run.
So that's another one of these short circuit type of operations,
although it doesn't look like it's a sort of Boolean expressiony thing,
but basically it boils down to being just that,
which I have to say I hadn't quite, these are things I'd not quite joined up in my own head
until I was writing this, and suddenly, oh yeah.
So you know, in fact, I'm sharing what I'm discovering.
But the fact that I discovered the might just point to the fact that I should learn more.
Anyway, I hope you find the exposition useful.
So the case two is going back to the yes equals one yes no business that I already talked about.
And you could write that as an if, and an airlif,
probably otherwise you could write it as well.
So my example here is I won't spell out every single character here,
but the same test of whether yes is equal to one in an if followed by a then.
After that, you would be able to create a directory because if yes is one,
then we want to create the directory if you remember.
But if it's not one, then we could ask the question with yes no,
do you want to create the directory?
And then create the directory if the answer is yes or not or fall through it if not.
So that achieves the same thing, but it doesn't use the short circuit business.
To me, the second one looks really ugly because you have to call the commands
to do the directory creation twice.
I didn't think of other ways of structuring it.
Maybe there are if you if you have a suggestion, let me know.
But it's it's it's ugly.
I mean, you could make the create directory thing a function and call it into places.
That would be cleaner.
But I just find that the first first way of doing it using the short circuit is better.
But you could argue that in a development environment where you're developing
stuff with co-workers, your colleagues might find the short circuities thing confusing
because it's not obvious what's going on until it's been explained to you.
So anyway, my conclusion of the question should it be used or not is yeah, I think it should.
And I certainly going to continue using it.
Finish by just saying there's a bunch of links here.
There's one to the short circuit evaluation Wikipedia page and pointer to the table,
which I found interesting.
But then I got carried away and put a couple more links in,
but conditional construct in programming, which I find quite interesting,
but it's not really relevant to this.
And also that took me to truth values in logic, mathematics and programming,
which is way out into the weeds, perhaps.
You might find it fun.
Anyway, that's it for now.
And I hope you found that useful and give me any feedback if you feel so minded.
Otherwise, see you again.
Bye.
You have been listening to Hecker Public Radio at Hecker Public Radio.
Today's show was contributed by a HBR listening like yourself.
If you ever thought of recording podcasts,
then click on our contribute link to find out how easy it really is.
Hosting for HBR has been kindly provided by an honesthost.com,
the internet archive and our sings.net.
On the Sadois status, today's show is released under Creative Commons,
an attribution 4.0 international license.