- MCP server with stdio transport for local use - Search episodes, transcripts, hosts, and series - 4,511 episodes with metadata and transcripts - Data loader with in-memory JSON storage 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
237 lines
19 KiB
Plaintext
237 lines
19 KiB
Plaintext
Episode: 2096
|
|
Title: HPR2096: Useful Bash functions - part 2
|
|
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2096/hpr2096.mp3
|
|
Transcribed: 2025-10-18 14:16:07
|
|
|
|
---
|
|
|
|
This is HPR episode 2096 entitled Useful Mash Functions, Part 2 and in part of the series
|
|
Mash Crypting.
|
|
It is hosted by Dave Morris and in about 23 minutes long, the summer is the further development
|
|
of a Mash Function that may be on use in your scripts.
|
|
This episode of HPR is brought to you by An Honest Host.com.
|
|
Get 15% discount on all shared hosting with the offer code HPR15.
|
|
Better web hosting that's honest and fair at An Honest Host.com.
|
|
Hello everyone, this is Dave Morris.
|
|
Now today I'm going to be talking about Bash and some functions that I think you might
|
|
find useful if you're into that type of thing.
|
|
Now this is one of those shows where I have put up quite a lot of code and I'm going
|
|
to talk about it.
|
|
So if you're not interested in this then you can skip ahead.
|
|
If you are interested I would strongly advise that you listen to this with the code in
|
|
front of you unless you have a very good ability to visualize bits of text in your head
|
|
which I'm certainly not such a person so I sympathize if you're not.
|
|
So what I'm doing today is picking up from where I left off in 2015, April 28th where
|
|
I did show number 1757 which I entitled Useful Bash Functions.
|
|
And so I thought I'd come from here and this is called also Useful Bash Functions Part
|
|
2.
|
|
And what I'm doing this time I looked back at the previous functions that I talked about
|
|
and I'd got a bit of feedback from the previous show.
|
|
Some of which said the way I had organized things was not really all that useful.
|
|
At the time I didn't agree with that but on reflection and on using these functions
|
|
because these are things I actually used day and day out.
|
|
I got really fed up with the way it was, I thought some of these were working so I've
|
|
rewritten them.
|
|
I thought I would share one of them with you which was the Yes No Function which was sort
|
|
of a bit, I think it was commented on that it was a bit annoying the way it worked.
|
|
So as usual if you have anything to say about this, critical or otherwise, anyway saying
|
|
constructive critically, critical things is a good thing.
|
|
So just please comment or send me an email or something.
|
|
So my Yes No, Yes Underscore No Function is a thing which I use in scripts which asks
|
|
a question in the form of a prompt and then expects an answer which has got to be a Yes
|
|
or a No positive or negative answer when then it will return a true or a false result.
|
|
And so what this function actually does is it takes a prompt and it outputs a prompt,
|
|
you feed it a prompt and you feed it a default answer which can be Y or N Yes or No.
|
|
And it then outputs that prompt and expects an answer or if you don't type anything it'll
|
|
go with the just hit return, it will go with the default.
|
|
Now the version that I demonstrated in show 1757, the prompt or not that the prompt was
|
|
always followed by the default.
|
|
So if you provided a default like yes or no or whatever, you would actually see, do
|
|
you want to do X Y Z followed by either the word yes or no.
|
|
So it actually, it typed it for you effectively which was not ideal because if you wanted
|
|
to change the default to something else it offered you no and you wanted it to be yes.
|
|
You needed to delete the text and then retype it.
|
|
So I've had to go at redesigning this and I've got two versions of it which I want to
|
|
talk about in this episode.
|
|
I've called them yes, no mark two and mark three.
|
|
So I've got an example of using mark two and it consists of if space exclamation mark
|
|
which is the not and the negation symbol in bash space yes, underscore no underscore
|
|
mk two space open quote do you want to continue question mark space percent S space close
|
|
quote space open quote capital N close quote semicolon space then.
|
|
So that's an if statement and the thing that follows the the then is return followed
|
|
by fi which is the end of the if statement.
|
|
So what this is doing is it's firing up yes no it's getting back an answer and if the
|
|
answer was true then it will return as the answer was yes it will return a true value
|
|
and then it will skip the rest of the if statement and carry on with the rest of the script
|
|
because we've negated it we've turned a true result into a false one and if the result
|
|
coming back is false it will be negated to become true and then the script will execute
|
|
the return statement.
|
|
So that's how it works.
|
|
So the prompt do you want to continue percent S is what gets put out and the the other
|
|
argument is the default.
|
|
So when you run it you would get the prompt do you want to continue question mark space
|
|
then you'd get square brackets low case Y slash capital N close bracket and that's
|
|
been replaced by the function that's replaced the percent S string now this low case Y slash
|
|
capital N business is a convention you'll often see in command line tools you probably
|
|
have and you're wondering why I'm telling you about it but just in case you haven't the
|
|
square brackets hold the two possible responses in this case which there's only two possible
|
|
responses and the default one is capitalized.
|
|
So this one shows that the responses should be a Y or an N but if nothing is typed
|
|
then it's taken as being an N and the case of these things is a relevant case in the
|
|
in the square brackets simply denotes which one is default.
|
|
So I then launch into the function itself and it's a bit different from the previous
|
|
version so I will go through this one but when we come to mark three I'll skip over
|
|
a lot of the details because they're similar.
|
|
So yes no mark two it starts I've got a numbered listing of it here in the notes in the
|
|
full notes starts on line nine preceded by the usual comment and on lines 10 to 12 there
|
|
are various variables being defined some of which hold two of which hold the arguments
|
|
the variable prompt and default hold the two the two arguments are given to it and also
|
|
provide defaults as appropriate in fact prompt is mandatory so that bit of bash parameter
|
|
substitution causes the whole script to fail with an error message if no prompt has provided
|
|
the default is set from argument two which is forced to uppercase it's just so we don't
|
|
have to bother about checking for for different forms of the the answer.
|
|
So lines 14 to 28 are all about dealing with the prompt string and as you've seen in
|
|
the example you can provide the prompt string with a percent s enclosure which is a substitution
|
|
point for this square bracketed business.
|
|
So first thing that happens on line 14 is that a bash regular expression is used to check
|
|
to see whether the prompt variable contains the string percent s I plan to talk about bash
|
|
regular expressions at some point in the in the future so I'll not go into details here
|
|
but if it is if there is one of these things in there then the rest of the lines up to 27
|
|
are executed if there's no percent s then we don't care we're just going to carry on we
|
|
don't need to do anything special to the prompt then on line 15 we have a check to see whether
|
|
there is a default value the minus n option inside the double square brackets which is bash's
|
|
testing capabilities in an if statement minus n means not blank not empty so if that's if the
|
|
default exists if there is a default value then we want to do particular stuff if there's no
|
|
default value then there's an error and we abort the whole script that's on lines 25 and 26
|
|
where an echo is produced which puts out an error message that says default required so if
|
|
you're going to use percent s you've got to provide a default or as it makes no sense and we
|
|
use on line 26 we use exit which not only exits from the function it also exits the script
|
|
that's calling it because whoever's written the the script is obviously messed up so we just want
|
|
to abort at that point so lines 16 to 23 now so what happens if there is a default and lines 16
|
|
we set default to the first character of that particular string because it might be a multi
|
|
multi character thing might be NO or YES or something then depending on what we get back there's
|
|
a case statement which begins on line 17 which is which uses default as the default variable as
|
|
the switch variable and if default contains Y then we construct reconstruct the prompt string
|
|
by using it as the format string to to a print f and adding square bracket what a capital Y
|
|
slash lowercase n closed square bracket as the percent s and we put that back into the prompt
|
|
variable so that's the line that says Y closed parenthesis print f space minus v space prompt space
|
|
open double quotes dollar prompt closed double quotes space double quotes square brackets
|
|
uppercase Y slash lowercase n closed square brackets closed double quotes and then two semi-colonzes
|
|
the way you end one of the branches in a case statement in bash so if the prompt was if the default
|
|
I should say was Y began with the Y then we want to put in the appropriate element in the
|
|
in the prompt string that shows that the default is for the end branch then we do the equivalent
|
|
thing but with the case the other way around so that the default is obviously a NO and in if we
|
|
get neither a Y nor an N which is the the star instance the star case in the case statement
|
|
that means anything else then we do another one of these echoes with an error message saying
|
|
the default must be Y or N and exit the whole script and the next line is a double semi-colon meaning
|
|
that's the end of that branch esac on line 23 is the end of the case statement I wanted to mention
|
|
how this echo error message is constructed the the echo string is in double quotes so you can put
|
|
parameters in it you can put parameters of substitutions in it and what we do is we substitute
|
|
dollar open curly bracket funk name f u n c n a m e all in capitals square bracket open square
|
|
bracket zero closed square bracket close curly bracket that means the array called funk name
|
|
the zero element now this is something that's maintained by bash and it keeps the name
|
|
of the current function that you're in on the it's it's sort of a stack similarly a bit further
|
|
on in that line we have a line number so it's line space and then the substitution point so
|
|
we're using dollar open curly bracket bash underscore line no which is all in uppercase in the
|
|
square bracket zero or close square bracket and this is the current line number that we're on
|
|
in the bash script so it's it's just I just put that in because I'd in the intervening
|
|
intervening time worked out how to do that and thought it's a useful thing to put in error messages
|
|
because you get more information about where things failed if you're developing a script so
|
|
after we've been all through all this stuff between lines 14 and 28 we've come out if we have
|
|
come out because we haven't bought it due to errors we've come out with a prompt string which
|
|
has been rewritten to contain this square bracket y slash n business so line 33 through 38 they're
|
|
pretty much similar to the original but I'll just read them quickly because you probably
|
|
have completely forgotten about how it was done originally so we've got a read statement read
|
|
space minus lowercase e space minus lowercase p and then the followed by space double quotes dollar
|
|
prompt close double quotes space a ns and so what that's doing is it's outputting a the prompt
|
|
and receiving back an answer which is storing in the appropriately named variable a ns then line 34
|
|
has got res equals in double quotes dollar question mark this is the result returned by the read
|
|
statement so if anything went wrong then we want we can catch it there and deal with it so this
|
|
is followed line line 35 to 38 by an if which says if dollar res is not equal to zero it should come
|
|
back as equal to zero meaning everything worked okay then echo re-deborted return one so the most
|
|
common thing that will happen is if if the person using the script can types control d which is
|
|
the sequence that you use to say that's the end of what I want to type and so then it's an end
|
|
file marker and you can use it to abort read prompts if you do that then the script will this function
|
|
will return a re-deborted message and will return one the value one is false so should have
|
|
returned the default perhaps I don't know anyways the trouble with reading these things as I think
|
|
about them I'm I'm thinking of other ways I could rewrite it anyway we leave it as it is for
|
|
moment and line 40 we're looking to check see whether an answer was actually returned whether whether
|
|
the the user just pressed return in which case the and variable will be of zero length and that's
|
|
what that test is doing it's using it's not using an if it's using one of these shortcut types of
|
|
bash expressions so in square brackets we have minus z space double quotes dollar a n s double
|
|
quotes and then ampersand ampersand space a n s equals open double quotes dollar default double
|
|
quotes so we're checking to see if if the and variable is empty and if it is and we put the
|
|
default in there then lines 41 to 45 are actually actioning the returned result so the if statement
|
|
checks to see whether the variable a n s which we force to uppercase is matches the regular
|
|
expression the regular expression consists of circumflex capital Y open parenthesis capital E
|
|
vertical bar capital E capital S close parenthesis question mark dollar now this is a regular
|
|
expression which looks for Y as the starting character and then that can be optionally followed by
|
|
an E or an ES and that's why they're in a parenthesis group with an alternate alternation vertical
|
|
bar in the middle if you've listened to my said series you should recognize this except
|
|
that in said you have to put backslashes in front of a lot of things the question mark after the
|
|
closing parenthesis means you don't have to have the things after the Y so just to plane Y or a Y
|
|
E or a YES or match and the dollar at the end simply says that's all you expect and you expect
|
|
the end of the line at that point so if that matches the script returns 0 which is true otherwise
|
|
it returns 1 which is false and that's it it's actually fairly simple except that there are some
|
|
slightly tricky things along the way if you're not up to speed with bash perhaps now there is a
|
|
problem with probably several problems with the mark 2 version and the thing that struck me as I
|
|
was developing this was that if you type Y you get the answer it treats it as if you're saying yes
|
|
but if you typed X or anything that is not an N including an N itself is regarded as no so that's
|
|
that's a bit messy if you accidentally if you went for the Y key and missed then it would be
|
|
interpreted as N and it could be something quite important that was being asked for confirmation
|
|
so I thought I would develop a mark 3 version to make like this a little bit more resilient and
|
|
it's essentially the same again it's listed in the long show notes it's pretty much the same
|
|
all the way through lines 1 to 32 everything is that it's pretty much the same the difference is
|
|
that online 33 we have a wild loop so there's a loop in this which will keep on checking what
|
|
is actually returned in the way of an answer the wild loop consists of the word wild space then true
|
|
semicolon space do I like to write my wild loops all on one line you can split it after the true
|
|
if you want to so the semicolon put the do on the next line so what's true well true is actually
|
|
a built-in feature it's a built-in bash command which just returns a true value true being zero
|
|
so while true do and the loop ends on line 57 means keep doing this loop forever there's no
|
|
condition there that will ever stop it so lines 37 to 42 are the same read and check and give up
|
|
on to control D thing that we saw in the earlier version of this in the mark 2 version line 44
|
|
is the same as before where it's checking to see if ANS contains anything and if it doesn't
|
|
setting it to a default then the real the real change the main change apart from the wild loop
|
|
is line 50 through to 56 where we check the uppercase version of ANS on line 50 against that same
|
|
regular expression that will match a Y or a Y E or a Y ES and then it will return true you know
|
|
that matches but then line 52 we're doing a further test that if it wasn't that then is it equal
|
|
to know where the the regular expression is circumflex capital N capital O question mark dollar
|
|
what that means is start at the beginning of the line look for an N followed by an O but the
|
|
O is optional because it's followed by that question mark and then we want the end of the line so
|
|
N O no way or something like that being typed in would not match if that matches we return
|
|
one which is false and if neither of those match line 54 the else branch we output the message
|
|
invalid reply please use Y or N and line 56 is the end of that compound if so what we have here
|
|
then is a thing that takes in an answer checks if it's yes or no and stops the loop annex it's the
|
|
function with a value but if neither of those are returned then it will produce an error message
|
|
and the loop will go around again so that the the functional keep on and on and on asking the same
|
|
prompt until it gets a valid answer so I've given a typical use in the notes which is which is
|
|
pretty much the same as the example for the mark 2 version so if I won't read that letter by
|
|
letter but if not yes no mark 3 then in quotes do you want to continue percent S close quote
|
|
the default is in quotes and it's a capital N semicolon then then we echo finished and we return
|
|
at that point so if you ran that ticket if statement in a script or from the command line if you
|
|
wanted to or it never do that myself personally but you you might get the following dialogue which
|
|
I've shown in the thing in the in the notes do you want to continue and you've got a lowercase Y
|
|
capital N so the default is no and who the the response here has been what it comes back saying
|
|
invalid reply please use Y or N do you want to continue in the same question type YO the previous
|
|
the previous version not the previous version the original version would have accepted that YO
|
|
as a valid as a meaning yes but in this case it says no valid reply and then the next answer is
|
|
NOPE NOPE well that also doesn't match because there's a P in an E after the NO invalid reply it says
|
|
and then asks the prompt again and finally this rather awkward person types NO which point
|
|
the script says finished and awards and stops exits so personally I say that the mark 3 version is
|
|
more useful overall and the one I'm I have adopted myself in a number of places and it's it's
|
|
just it's not perfect there's still things you could do to it actually some of which I thought
|
|
of as I was reading this stuff but yeah it's it's a bit better if you have for any input if you
|
|
have any suggestions as to how to make it better then please let me know there's a version of it
|
|
which can be downloaded which is linked in the notes so if you want to grab it and use it in
|
|
your script or mess around with it or improve it or whatever then please feel free and if you do
|
|
improve it as I said let me know that would be great okay we'll call it quick stay hope you
|
|
enjoyed that bye now
|
|
you've been listening to Hacker Public Radio at Hacker Public Radio dot org we are a community
|
|
podcast network that releases shows every weekday Monday through Friday today's show like all our
|
|
shows was contributed by an HBR listener like yourself if you ever thought of recording a
|
|
podcast and click on our contributing to find out how easy it really is Hacker Public Radio was
|
|
founded by the digital dog pound and the infonomican computer club and it's part of the binary
|
|
revolution at binrev.com if you have comments on today's show please email the host directly leave
|
|
a comment on the website or record a follow-up episode yourself unless otherwise status today
|
|
show is released on the creative comments attribution share a light 3.0 license
|