Files
Lee Hanken 7c8efd2228 Initial commit: HPR Knowledge Base MCP Server
- 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>
2025-10-26 10:54:13 +00:00

410 lines
31 KiB
Plaintext

Episode: 1648
Title: HPR1648: Bash parameter manipulation
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr1648/hpr1648.mp3
Transcribed: 2025-10-18 06:19:58
---
It's Wednesday 26 November 2014, this is HPR Episode 1648 entitled Bash Parameter Manitulation
and is part of the series Bash scripting.
It is hosted by Dave Morris' and is about 41 minutes long.
Feedback can be sent to Dave. Morris' at mail.com or by leaving a comment on this episode.
The summary is a summary and aid memoir of Bash Parameter Expansion Methods.
This episode of HPR is brought to you by An Honesthost.com.
Get 15% discount on all shared hosting with the offer code HPR15, that's HPR15.
Get your web hosting that's honest and fair at An Honesthost.com.
Hello, Hacker Public Radio, this is Dave Morris.
Today I'm bringing you a show which I'm calling Bash Parameter Manitulation.
So let me set the scene a little bit.
I'm a keen user of the command line.
I tend to live mostly in the command line or in a web browser, or possibly an editor.
That's largely the command line's largely because that's all there was back in the days
when I first started using computers back in the early 70s.
In fact, in many cases there wasn't even that.
It was punch cards or something like that.
But so I tend to think in terms of commands that I type to a computer a lot of the time.
In those days the commands were pretty primitive, nowhere near as flexible as they are now.
But they did have the concept of being able to put commands in a file which you would
then be able to execute, and that's what we now call a script.
In those days it was called a job command language file or a macro in some context.
Various other names I'm sure that I've not come across.
So the concept of a script of a bunch of commands in a file means that you can effectively
use the command line, the commands that are available to you in the command line as a type
of program.
These things use what they often call variables or parameters to hold data for intermediate
use.
So you'd store something in there and then use it and then discard it.
So what I want to talk to you about today is this business of parameters or variables.
And I want to do that in the context of the bash scripting language.
Bash is the name of one of the unique shells available to you on a Linux system.
It stands for Born Again Shell which is a play on words because it comes from the original
shell SH and it was rewritten by a guy called Born.
So Born Again Shell is a sort of rubbish joke.
Anyway, it's part of the GNU project and it's generally available and it's pretty popular
I would say, certainly the shell that I use.
I guess I'm jumping in somewhere in the middle of bash here.
You might be asking, well, why aren't you talking about bash from the beginning?
Well there are a number of shows that talk about using shells, particularly bash, I think,
in the HBR archive and I've put details of these in the show notes.
I did consider starting a whole series on this and maybe I'll start in the middle
and then begin again at the start or something like that.
I don't know.
It depends how enthusiastic I feel about the whole thing.
The reason I'm doing this particular show is because the bash shell has got some quite
sophisticated features in it currently, the current release which I suspect a lot of people
don't know about.
Obviously I would imagine most advanced bash users do know about these but I wouldn't
class my stuff as particularly advanced and it took me a while to discover these and
to fully understand what they were about.
What I tend to do and I find something like this and need to get my head around is to
write stuff down for my own consumption, maybe something I can stick up on a pinboard
to remind myself, or have a cheat sheet available in a folder that I can look at to remind
me how to use it.
Something that condenses the information down into a minimal space.
What I've done for this show is to give you the two cheat sheets that I've constructed
for this, one of which is really just a lift from the bash man page but I've reformatted
it and put some emphasis in it and so forth and put it into a table, it's probably a
little bit easier to read.
The other thing I've done is to prepare a diagram with examples of these various features.
So I won't be referring to these again but they're part of the bundle that I'm putting
up on HPR to accompany this show so I hope you find them useful.
Otherwise most of what I'm talking about is covered in the show notes themselves.
In fact you might find the show notes going a bit more depth than I speak about because
I don't want to make this show too long to tell you about stuff that you can read.
So I guess it's probably a good idea to start with just looking at what a variable is and
how you work with them in bash.
I imagine most people will know this but it probably does no harm just to quickly whizz
through this.
So a parameter or a variable is a simple thing that holds a value and you might type something
like username equals followed by some string.
The string actually can be enclosed in double quotes or single quotes or it can just be
a bare set of characters.
You need to put quotes around it if you've got spaces in it.
So username equals and then the string to set up a variable called username.
There mustn't be any spaces before or after the equals sign.
That's really important because the bash parser will immediately stop parsing this as a
variable declaration if it finds spaces here.
If you then want to use this parameter that you've called username then you can use it in
an echo command or in various other places.
My example shows it being used in an echo.
You just proceed the name of the variable with a dollar sign and it will, echo will print
out the contents.
So there's an example in the show notes of how you would do this.
There are times when the variable name and the string that you're trying to embed it
in perhaps it's hard to tell where one ends and the next begins and in those cases you
can put curly brackets or otherwise known as braces around the name of the variable after
the dollar sign.
So this would be dollar sign, open curly bracket, username, close curly bracket and that
makes it completely unambiguous.
And you do need these braces when you're doing some of the tricks with variables that I'll
be talking about.
The other type of variable that I'm sure people know about but again it's worth maybe
skipping through fairly rapidly is an array.
It's possible to define an array in bash, array being a structure which contains multiple
pieces of information.
And the simplest form of this is an array which is indexed by integer numbers starting
at zero.
You can either declare this as a bracketed list so my example shows weekdays equals open
bracket.
This is a round bracket.
Trying to be consistent with the naming for these things, I know there are differences
between the UK and the States to how these things are named a parenthesis, we call it.
Open parenthesis, Monday space, Tuesday space, Wednesday etc. throughout the weekdays
and then close parenthesis.
That will declare a variable, an array variable called weekdays which contains elements which
are indexed as zero, one, two, three, four and each of these points to a specific weekday
name.
You can if you wish to declare these things, my second example is a weekend square bracket
zero equals quote Saturday, quote.
What that does is to declare an array called weekend, the first element, the zeroth element
of which is the string Saturday.
So that's a very simple and quick definition of what arrays, how you would create an array.
There are other types of arrays, there's associative arrays which are hash tables which can be indexed
by strings in bash as well but I'm not going to talk about those.
So when you want to refer to an array, here you have to actually use the braces that I
was mentioning before.
So if you wanted to display the contents of the array weekdays index by four, then you
would type echo, space, dollar, brace, opening brace that is weekdays, square bracket four,
close square bracket, close brace.
You can see this in the show notes.
So that would get you that specific element and that would report it.
An entire array can be echoed or printed or used in various contexts and that in that
case the index that you use is an at sign or an asterisk.
They do have different meanings but I won't go into those just now.
So I'm mentioning these because the examples that I'm going to talk about will use simple
variables and arrays.
So one of the things you often see in scripts is maybe setting a variable.
So I've got an example under the heading manipulating parameters where a variable called date
is being set to 2014 hyphen 10 hyphen 27 or enclosed in single quotes.
So you might set it to a value like that just a literal string.
There are other ways that you can set variables to the result of expressions as well.
So the next statement in my example here is a month.
I want to extract the month value from a string like this.
And so that consists of a statement that says month equals.
Now here we have an example of setting a variable month to an expression.
In this particular case it's a little set, it's a it's a couple of commands, a pipeline
of commands which will produce a value and will return it.
And what you often see is a thing like this, dollar sign, open parenthesis, echo dollar
date. So that will cause the date string to be output to stand it out.
And then a pipe symbol, a vertical bar, then you pipe that into the command cut minus F2.
That means get field number two, which is the one, the 10 is 2014 hyphen 10.
And minus D, open quote, hyphen, close quote, close parenthesis.
What that says is cut second field where the fields are delimited by hyphen or dashes
have you like to call them.
So that is a way of doing this and then you'd find that with an echo which says the month
number is dollar month and you would get back 10.
But doing it that way means that you've had to invoke an echo, you've had to invoke
a cut in a pipeline to extract the relevant piece of information.
This has caused a whole bunch of processes to be fired up to do a pretty simple thing
picking a couple of characters out of a string.
Now this is, you can do this in within bash itself without the overhead of creating processes.
And there's a feature called substring expansion within bash where you would specify month equals
dollar, open brace, date, colon five, colon two, close brace, where what that's doing is
it's going to the fifth element starting from zero, indexing the string from zero and
grabbing two characters from that position.
So that sets the variable month to the characters of date from position five, four, two characters
and it achieves the same thing as the echo date cut that I mentioned before and it does
it a lot more efficiently.
Now you may be saying who cares about efficiency, I've got a Intel i7 machine on my desktop
and it's got more power than I ever used.
Why do I care about this sort of thing?
Well, I believe that it's a good practice to be thinking about these things when you're
writing scripts because the day will come when you're trying to write a script to run
on a Raspberry Pi or something even less powerful than a Raspberry Pi.
And you might find that the overhead of running something that creates processes to do
this will be such that it becomes very slow, especially if you're doing it a lot.
And so thinking about the efficiency of these things is quite an important thing to do.
It's certainly part of my history working in the Unix world for a large number of years
back to the days when they were probably a lot more feeble than a Raspberry Pi.
So let's cut to the chase then.
The various functions I'm going to talk about, they have names or at least they have various
titles in the bashman page.
You won't find these in some of the online resources, but I'm using them just as a convenient
way of referring to them.
So let's start with the one that's called use default values.
In this case, when you are substituting a parameter, you're expanding the parameter,
then you can test to see whether it's defined or is no, whether it actually contains a value.
So I've got an example here where the first line says unset name.
So we've got a variable called name, we're unsetting it, we're removing it, we're deleting
it totally, assuming it exists.
This is followed by echo, dollar, open curly bracket, name, colon, hyphen, undefined,
close curly bracket.
What that says is, if name is defined, then echo its value.
If it's not defined, then provide the word undefined.
Now, because we've just unset it, this particular expression will return undefined.
So that's a way of testing whether a value is set or not in a script.
So if we continue and set the value, you've got an example here that sets it to the name Charlie,
then we echo it, then using the same expression as before, then we see the value Charlie returned.
Next we have the one called assigned default values.
Now, this is a similar sort of idea except that it sets the variable to a value.
So I'm using here a variable called page, and I start by unsetting it, make sure that
it is, it doesn't exist.
Then echo, dollar, open brace, page, colon equals, portrait, close brace.
What that's doing is, if the value is not set or it doesn't exist, then set it to the
string portrait.
I'm assuming that this is something using the page orientation value in a script.
So in this particular case, it's not set.
So the result would be returned as portrait.
If we then echo it, so the next line says echo dollar page, then it contains portrait.
So not only was it recognized that it wasn't set, but it was set to that particular value.
So if we now set it to new value, landscape, which is the next line, then do the same
expression again, then the result is landscape, it's not portrait at all, because the test
is it set or is it null, came back as false.
So therefore we just use the value moment and echoing it there after we get landscape.
But that's quite a useful thing to do in a script where you're maybe setting something
from an argument and you want to give it a default if it's not been supplied.
Next we have display error if null or unset.
And this is another test which will produce an error and cause the script that's doing
this test to exit if a parameter is not set.
So this one, the example is an echo dollar open brace length colon question mark, then
you follow that with the error message you want to produce, which in this case I've put
length is unset, close brace.
This will produce an error message which contains somewhere, it will contain a prefix which
talks about where about in the script it's failed, I've not included that in my example.
But you will get the name of the variable length followed by a colon and the error message
that I mentioned length is unset.
This one is called use alternate value and this one checks if the parameter is null or unset.
And if it is, then nothing is substituted otherwise it is.
So the example says fish variables fish equals trout and then we echo dollar open brace
fish colon plus salmon and close brace and the result is we return the value salmon.
So in this particular case the parameter is not null and it's not unset and in this case
we return the value in the in the braces.
But then the next line in the example shows echoing the variable fish and it's still
set at trout.
I must admit I never used that just off the top of my head I can't think of many instances
that I'd want to but due to my lack of imagination more than anything else.
So that's the bundle of functions which test for values and do various things as a consequence.
The next one is called substring expansion and I've mentioned this already briefly.
It takes a variable so you do dollar open brace name of parameter variable colon then
a number then another colon and another number and close brace.
What that's doing is it's the first value is an offset into a string into the variable
and the second one is a length.
If the length part is emitted then it means just all of the string from that particular
point from that from the offset.
A negative offset means to count backwards from the end of the string but because that
would result in the sequence colon minus which we've already seen earlier on you've got
to put colon space minus if you're going to do this thing in order to avoid being misinterpreted
as the default value form.
If you give a negative length then it's not really a length but it means to return the
string between the offset and the position backwards from the end of the string which
is difficult to get your head round up and you can also index sections of arrays with
this stuff.
So here's there's some examples here which I'll go through quickly I mean hopefully you
will be able to follow them yourself.
So if you set a variable animal to equal the string R bar then if we echo dollar open
brace animal colon 4 close brace then what we're saying is display the string from position
4 to the end and remember that these are indexed by index from 0.
So the fourth character the index 4 is the V followed by the rest of the string which
returns a VARC.
If we set a variable message to the string no such file then echoing this message from
position 0 4 7 will pick up the first 7 characters which will be no such.
Taking the same variable message and making the offset minus 4 then you will get the last
4 characters of the string which is file.
And echoing message with an offset of 3 and a negative length of minus 4 will pick up
the word such because 3 is the position of the S of such and minus 4 counts backwards
from the end of the string so it will skip over the four letters of file, reduce such.
If we look at the next example we've set a variable which is an array to equal in parentheses
the names red, orange, yellow, green, blue, indigo, violet, close parentheses and if we
then wish to index elements of this we can do it with dollar open brace colors with an
add in square brackets thereafter so that means that's a way of indicating the entirety
of the array, colon 1, colon 3 that means go to element 1 remember they count from 0 and
return 3 elements so that will return orange, yellow and green.
The next one is using the same colors array dollar open brace colors, open square brackets
at close square brackets colon 5 what that means is go to element 5 which is indigo and
return all the rest of the elements which is be indigo and violet.
This is quite powerful you can do a lot of quite interesting things with this in a script.
The next one names matching prefix never really needed to use this but like I say it's
probably due to my lack of imagination more than anything else.
This is a way of interrogating bash for the various variables that it knows about.
The example I've given here echo dollar open brace exclamation bash capital B a s h
asterisk close brace.
What that's saying is return me all variables whose name begins with b a s h and it's
quite a long list I haven't listed them on it but things like bash bash hops bash pit
these are all variables which if you look at the man page you will find described.
The next example is simply example of creating two variables called coord underscore x and
coord underscore y setting them to values if I then wanted to find out what the names
of these variables were then echo dollar open brace exclamation coord cwr d asterisk close
brace returns the two names that I just mentioned coord x and coord y the next one is something
a bit more useful this is returning a list of array keys it's actually more often array indices
but keys are the more generic term since remember there are there are indexed arrays indexed
numbers and raised indexed by strings which we didn't deal with earlier on so here we're
setting an array colors to equal the three names red green blue and if we then provide
the expression echo dollar open brace exclamation mark colors bracket
excuse me bracket square bracket at closed square bracket close brace then we see the indexes
which 0 1 and 2 the next one is about the length of a parameter and it can also be used with an
array where it returns a number of elements you might have seen something similar to this when
you're looking at the arguments to a script I'm not really dealing with the numbered arguments
in this talk so what we have here in in terms of example is a variable veg vg equals set being set
to the string broccoli if we then echo dollar open brace hash mark pan sign for americans v e g
close brace we get back length of the string which is eight now the next example is a case
where we are setting an array array dt equal to the result of a command and so if I just read this
out to you dt equals open parenthesis then follow that with dollar open parenthesis again date
close parenthesis close parenthesis what that's doing is the the inner dollar
parenthesis date invokes the date command which returns a string which which consists of the
various bits of the date the day that day number and the year and so on so forth forget the actual
order but you can try it yourself and see that's the whole thing is enclosed in parenthesis which
is a way of declaring an array so what happens is each of the separate pieces the six fields
that are returned by a date are dropped into this array because of spaces that is the
delimiter that bash expects so if we then echo dollar open brace hash sign dt then open square bracket
at close square brackets close brace that's again just remember this this defines it as an array
and we're talking about the entirety of the array then the answer comes back as six so it's a useful
way of finding out how long an array is now we're coming on to some more interesting features for
manipulating the internals of strings and arrays this one's called remove matching prefix pattern
so this as you might gather removes characters from the front of a string the the general format
is the name of the variable followed by a hash sign followed by a pattern that is to be removed
now the pattern that's mentioned is similar to the sort of patterns you can use when you're
searching for files on the command line in things like ls or whatever so it can contain an
asterisk meaning an arbitrary number of characters for example now in my examples I start off with
setting a variable called dir dir equals to a path a file path in which which case is slash
home slash Dave slash some slash dir so if I then echo dollar open brace dir the variable name hash
slash home slash Dave slash close brace what that's saying is from this variable from this string
remove slash home slash Dave slash from the front not too surprisingly we get back the string
some slash dir if we did this differently and use the expression dollar open brace dir hash
star slash close brace what that's saying is the first number of any characters that are not
a slash followed by a slash to be removed from the front well there are no characters other than
a slash on the front so it just takes the first slash off and it returns home without et cetera
without the leading slash if on the other hand we use two hashes which is the other the other
capability of this particular function then we would use dollar dir hash hash star
asterisk I mean slash close brace then what that will do it will return it will remove all of the
strings followed by a slash until around a more so that will remove everything until the last
component of this path name so this is similar to the built-in base name command that's available in
bash and it's it's a more efficient way of achieving the same same thing as base name personally
I prefer to use it for the reasons I mentioned before if we have an array and I've got an
example where I'm setting an array colors are equal to red the name the red green and blue but
each name has got an underscore on the front of it so if I then want to strip these off then I
can set color and save them back into the array I can set colors equals open parenthesis dollar
open brace colors open square brackets at sign close where brackets hash underscore close brace
close parentheses so what that's doing is defining colors as a new array array definition
remembers in parentheses and inside this array definition is this substitution pattern which is
dollar open brace colors blah blah blah hash underscore what that's saying is process each
element of the array as it stands at the moment strip off the underscore from the front of each
character and drop it back into the array so if you then echoed the the array this example here you
will find red green and blue being returned without the underscores on the front so this was that
was the prefix that was stripping prefixes then there's similar one that removes suffixes from
the the ends of strings or arrays this one also uses a pattern which should which can contain
asterisks and other things but I'm not going into details of that just now but the difference is
that instead of the hash it uses a percent sign so the the variable DIR is being set to the same
things before and if we then echo dollar open brace DIR percent slash some slash DIR close brace
what that means is strip off slash some slash DIR from the end of it and not too surprisingly what
we returned is slash home slash Dave if on the other hand we echo the the expression dollar open
brace DIR percent slash star close brace then what that's saying is remove from the end a slash
followed by arbitrary commands arbitrary characters I mean so that will strip off the slash DIR
from the end giving you slash home slash Dave slash some if on the other hand we wanted to
remove more from the end of the thing and do it in in using the double percent which the
quimp the double hash dollar open brace DIR percent percent slash slump some slash star close brace
that will remove slash some slash DIR from the end of it leaving you the string slash home slash Dave
so using this slash star business slash asterisks if you prefer then you have a similar effect to
the DIR name command that is built into debash so I gave another example not using arrays this time
where it's a quite common thing to do where you you strip off the extension of a file name so
I've got a variable called file name which I'm setting to great underscore view dot jjpg so what we
want to do is to change its name from dot jpg dot png so that can be done by setting file name
equal to and then a string in double quotes dollar open brace file name percent dot jpg close brace
dot png so what that will do is it will take file name it will strip off the dot jpg as we've seen
from the end and then it will append to the what's left the string dot png so the result will be
great underscore view dot png that's that can be a pretty useful thing to do in fact I use it
sometimes it using image magic they're the convert command in image magic so you can change the
format of a file from jpg to png using using that sort of expression in the command so the next one
and we're getting close to the end now is patent substitution now this is quite a powerful
facility that lets you make substitution within a string and the the general syntax is that the
name of the the variable is followed by a slash and a string a pattern followed by another slash
and the name thing that is that the string that is to replace it so if we take my example then I'm
setting a message to the wonderful string and and is and and don't know what possess me to do
that but there you go then we echo dollar open brace msg slash and slash insect close brace then
it will return the string and insect is an ant okay now that's pretty trivial if you use a percent
sign following the slash then it matches at the end of the parameter so if you can have slash
percent which means which means something completely different than just a straight slash when
you're doing the pattern matching so I've got an example here where dollar msg slash percent
and slash insect close brace doesn't change it to an insect as an ant but it changes it to an
ant is an insect so it's changed the last instance of ant to insect rather than the first then if you
have if you use double slashes after the name of the the variable then it changes all instances
of the pattern throughout the string so I've got dollar open brace msg slash slash and slash insect
close brace and it changes the string to an insect as an insect it's changed both instances of ant
you can do similar things with arrays as well and there's an example in the show notes which I won't
go into because I think I've gone on a bit too long as it is the final one then is case modification
so you can change the case of characters in a in a string in this particular case in this
sorry that's a bad pun in this instance you use an an up arrow symbol to mean to which means
change letters to uppercase I was just trying to remember what that up arrow thing is called
but I can't remember and use a comma to indicate lowercase so the there's various examples
showing how you can change the first character in a lowercase string to uppercase or you can
change all of the characters to uppercase and you can also do specific pattern matches throughout
the string I used a pattern including a square bracket a square bracketed list of characters to do
character matching hopefully you'll be able to work that out from the example this is quite
lengthy so I won't go into into great details here so that's the list and that's it and I hope
you find it useful what I should what I would have liked to have done was to have given you some
examples of using it but of using these various features but I didn't do that because I thought
this is getting a little bit too complex anyway but if you look back at one of my earlier shows show
number one two oh four about some scripts I wrote to download music from the magnitude website
in as part of that I produced a bunch of scripts which were put up on the guitarist website and
give links in there to these bash scripts they're all written in bash in those you will find that
I've used a fair number of these things and there's they're also annotated there's quite a lot
of detail explaining what the various parts of these scripts do so if you're up to poking around with
the the guitarist site you might find some stuff there that's quite useful okay that's it hope you
enjoyed it you've been listening to hecka public radio at hecka public radio dot org we are a
community podcast network that releases shows every weekday Monday through Friday today show
like all our shows was contributed by an hbr listener like yourself if you ever thought of
recording a podcast then click on our contributing to find out how easy it really is hecka public
radio was founded by the digital dog pound and the infonomicon 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
stated today's show is released under creative comments attribution share a light 3.0 license