- 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>
224 lines
20 KiB
Plaintext
224 lines
20 KiB
Plaintext
Episode: 2709
|
|
Title: HPR2709: Bash Tips - 16
|
|
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2709/hpr2709.mp3
|
|
Transcribed: 2025-10-19 07:56:14
|
|
|
|
---
|
|
|
|
This is HPR episode 2007-109 entitled Bashtip, 16, and in part of the series Bash Crypting.
|
|
It is hosted by Dave Morris and is about 24 minutes long and carries an explicit flag.
|
|
The summary is Arain in Bash Part 1.
|
|
This episode of HPR is brought to you by an honesthost.com.
|
|
Get 15% discount on all shared hosting with the offer code HPR-15, that's HPR-15.
|
|
Better web hosting that's honest and fair at An Honesthost.com.
|
|
Hello everybody. Welcome to Hack Public Radio. This is Dave Morris and I'm talking about
|
|
Bash again, Bashtip's number 16.
|
|
I've dropped using the titles with interesting words from the Thessauras.
|
|
As I mentioned on the community news, so yeah 16, so what I'm doing now is talking about
|
|
a raise in Bash. I'm going to do a bunch of shows on the subject to try not to make each
|
|
one too long. So we've encountered Bash arrays at various points throughout this sub-series
|
|
I've referred to them and given examples using them but never really explained them.
|
|
So now's the time to get into some explanations.
|
|
First thing is that there are two types of arrays and they're called indexed and associative.
|
|
They're both one-dimensional so other languages have multi-dimensional arrays but not in Bash.
|
|
Indexed arrays are indexed by positive integers starting at zero but the indices don't have
|
|
to be sequential so you can have gaps. That's called being sparse.
|
|
Active arrays are indexed by strings and if you following this series on Ork then we've
|
|
talked about the equivalent in that language. Both rate types have no limit on the length
|
|
and the actual values you store in there are strings. It might be numbers.
|
|
Well actually it's not quite as simple as that but I'm not getting to that particular point
|
|
for a while, not in this episode anyway. So there are several ways of creating and
|
|
raising Bash and the methods of doing it very slightly between the two types.
|
|
So let's first look at indexed arrays. First thing is that you can simply create an index
|
|
array and put a value in it by using the format name where the name is the name of the array.
|
|
Then in square brackets the subscript that would be a number indexed array.
|
|
Then after the closing square bracket equals and then a value which can just be an
|
|
unquoted word if you wish but usually wiser to quote things because Bash can contribute
|
|
up if you don't put quotes around strings. So I've got an example which shows an array
|
|
called fruits and element zero in square brackets is being set equal to the string apple.
|
|
It's one it's being set to pair. So fruits is the array name and there are two subscripts
|
|
which are zero and one subscripts or indices whichever you like to say and so it's an assignment
|
|
but if you've used any languages that you use to raise this will not be a big surprise
|
|
this is the way it's usually done. The subscript must be a number or an expression but it's
|
|
an expression which we evaluate so a number string would not do. So I've got an example
|
|
where a variable i is set to zero then fruits dollar i as the subscript set to apple then
|
|
i is incremented in an arithmetic assignment and an arithmetic expansion I should say inside
|
|
the square brackets so plus plus i is in two round brackets two parentheses with a dollar
|
|
on the front. We looked at this stuff in show 1951 which is a link to in the show notes.
|
|
So that is being set to the value pair then we do the same again fruits open square brackets
|
|
dollar two open parentheses plus plus i two close parentheses close square brackets equals
|
|
then in quotes grape so we're just incrementing that variable it started to zero each time
|
|
we add a value to it. It's not the best way of doing it it's just to prove that that's
|
|
a way of doing it. There's also a thing called a compound assignment where you use the name
|
|
of your array so I've got the sort of generic form name equals then open parenthesis followed
|
|
by a list of things and close parenthesis. The list is square brackets containing a subscript
|
|
equals value so that would be for the first element then another one square brackets subscript
|
|
to close square bracket equals value two and so forth you can have as many of those as you want
|
|
I've just put two in my example. So I've rewritten the last example where we set each value
|
|
into the array fruits by doing one per line and there's a compound statement a compound assignment
|
|
which sets them all in one line. I want to read this out because it's pretty much the same as before
|
|
but laid out differently if you like then again the subscript equals part is optional if what
|
|
is doing is starting is zero and going up in in incremental steps incrementing by one each time
|
|
so you can write it as fruit equals open parenthesis then in quote apple space in quote pair
|
|
space in quote grape close parenthesis so that's there's been signed to element 0102 and what's
|
|
happening is bash is seeing each of these items in this parenthesis list and is simply incrementing
|
|
the index all by itself before it is it assigns it to an array element there's also a way in which
|
|
you can take an already existing index array and append to it by typing in this particular case
|
|
fruits plus equals open parenthesis quote banana close quote close parenthesis I should say and
|
|
that depends to it so it sticks banana on as the the fourth element one with the index of three
|
|
remember zero is started zero plus equals operator is I think a fairly recent addition to bash
|
|
some people have seen and had to done this myself forget but the plus in front of the equals so this
|
|
is not the same thing and if you were to to type fruit equals open parenthesis banana to an array
|
|
that had already been loaded with some data it's going to clear it completely and just add the one
|
|
element the zero element will be banana so watch out for that another way to define an index to
|
|
array is with the declare built-in command now I'm going to look at declaring a bit more detail
|
|
later on in this group of shows but I'm not not going to go into great depth today but anyway declare
|
|
space hyphen lowercase a space and then a name in fact a list of names will create a bunch of array
|
|
variables which are indexed arrays declare can be used to create other things so you need to say
|
|
what type of thing you're creating and that's what this hyphen lowercase a does so that's in
|
|
indexed arrays so they can be really simple or you can be more formal about it and do use declare
|
|
however when it comes to creating an associative array you have to start with the declare you can't
|
|
do the explicit indexing stuff because how could you the the indices or subscripts are strengths
|
|
any old string you care to come up with so there is no implicit thing you can do it has to be an
|
|
explicit definition but the initialization of an element is done pretty much the same way name
|
|
square brackets subscript close square bracket equals value the subscript that you put in between
|
|
the square brackets doesn't need to be quoted if it contains a space but other characters which are
|
|
not just simple spaces and letters numbers might need quotes so I've got an example here where
|
|
we declare I didn't say that you had to use a hyphen capital A to define an associative array I
|
|
skipped over that bit so if you did declare space hyphen capital A space capitals then
|
|
got an example here where we're initializing capitals square brackets England is set to the
|
|
string London Scotland Edinburgh Wales Cardiff Northern Ireland Belfast Northern Ireland has got
|
|
a space in it and they haven't quoted it in here and that that's worked fine you can also use
|
|
compound assignment as we talked about with index stuff declare space hyphen capital S space
|
|
capitals and then you would do capitals equals open parenthesis then you've got to put the subscripts
|
|
so square brackets England's close square bracket equals London and so on and so I've quoted the
|
|
the values in all these cases because it's just wise too as I said before you can even stick those
|
|
two things together and you can declare you populate the array at the time you declare it so
|
|
so after capitals in the declare command you can just put equals and then in parenthesis the list
|
|
of things you're you're setting up I've got an example here that shows it you can do the same with
|
|
the indexed arrays as well I didn't mention that earlier so I've got an example here of how you
|
|
would create an associative array called char chrs in which I'm assuming you would be storing
|
|
certain characters and when you look them up you would get back and a textual description of
|
|
what the character is so I've got declare space minus capital A space chrs then you set the
|
|
an element chrs open square brackets quote I've used a single quote open square bracket so that's
|
|
the character close quote then another close square bracket equals and then the string open square
|
|
bracket but you'd have to quote those square brackets that you're using as the subscripts
|
|
not too surprisingly because there's this lots of scope for confusion there so how do you get hold
|
|
of the contents of an array having initialized it in some way or another and there are other ways
|
|
that you can initialize it than we've seen so far but I'm not going to go into those in this
|
|
episode they'll come later so one of the simplest ways of visualizing the contents of either type
|
|
of array is using declare with the argument hyphen lowcase p and this what this does it just
|
|
generates a string which you could save away somewhere which is actually the command you use
|
|
or would could use to create the array in the first place so we've got for example the three
|
|
arrays that we've been talking about so far declare space hyphen p lowcase p that is space
|
|
fruits space capital space chrs and what you get back is a bunch of declares declares space hyphen
|
|
a fruits equals and because this this is a lowcase a and because the this one's an index array you
|
|
just see the parenthesized list of subscripts and values if you did it if you um look at the
|
|
declare hyphen capital A capitals then you see the um the list of subscripts and values
|
|
starting with square brackets quotes northern island quote close square bracket equal
|
|
bell fast in quotes you get the general idea hopefully the ordering that you get stuff back in
|
|
when you you run this command and really you use this if you were saving the structure of an
|
|
an array maybe to rebuild it later on in a script or something or in fact you might have been
|
|
populating it from some data and you want to save it away back it up the order which you get
|
|
stuff back is is always in index order when it's an index to array but when it's an associative array
|
|
there is no defined order we just happen to get them back in the order we're seeing here and
|
|
bash when it reports them back quotes the strings the subscript strings in an associative array
|
|
but you can emit most of them when you're doing itself as long as you're sensible about it
|
|
so that's one way of seeing what's in an array but when you're doing you're developing stuff
|
|
the usual way that you access array elements is with the syntax dollar because you're
|
|
expanding a variable but this time you put an open curly bracket the name of the array
|
|
then in square brackets a subscript which can be an expression or a constant close
|
|
square brackets close curly bracket so that's how you access an array element
|
|
the curly brackets you need them in order to avoid any conflict with bashes
|
|
file name expansion operators now when I first saw this I wondered why why can't you simply
|
|
write something like dollar fruits square brackets one that would be the logical thing to do
|
|
but the problem is that the way bash is structured that would be parsed as the variable dollar
|
|
fruits or the variable fruits being expanded because of the dollar on the front and the square
|
|
bracketed number will be regarded as a glob range expression you know those things where you have
|
|
open square brackets one hyphen nine or something like that so that would not give the result
|
|
that that's wanted I did a few tests to see what would happen if you did that given I was working
|
|
in an environment where I had the various arrays that we've been looking at so far what would happen
|
|
so I echoed dollar fruits square brackets one and I get back the expansion of fruits and you get
|
|
back the first element followed by square brackets one which is pretty well meaningful meaning
|
|
less sorry not meaningful as what I was going to say and that's partly because if you
|
|
use the name of an array without any subscript then that's interpreted by bash as the element with
|
|
index 0 I get the first first element and an index to array it also has the same meaning when
|
|
you come to an associative array which I think is a bit odd the following example though is showing
|
|
if you declared a associative array so it's a hyphen capital A and I've called it hash and in it
|
|
I've created an element with subscript of low case a value 42 low case b subscript value 97 and a
|
|
value subscript of zero and I put the string what is this question mark that's all in parentheses
|
|
if I echo the array hash just by giving it dollar hash what I get back is that bash has interpreted
|
|
hash as being the first element or the zero element or indeed even more weird the element which
|
|
has the index zero well it just happens to be one is the string zero but you get back the string
|
|
what is this now that's very strange so I think I'm trying to prove here that you should not
|
|
emit the curly brackets because you're going to be in a whole whole painful area which you're going
|
|
to regret I think because you struggle to work at what an earth is happening if you put the curly
|
|
brackets around this stuff then you would type echo space and then in double quotes don't
|
|
strictly need double quotes but it's always wise to put them in dollar open curly bracket fruits
|
|
open square bracket one closed square bracket close curly bracket close quotes and you would get
|
|
back the word pair because that's the element with index of one so that's how you access an individual
|
|
array element if you want to do something where you look at all of the elements of an array
|
|
then instead of using a subscript which is a number or a string two special subscripts which
|
|
you can use the first one is an at sign and the second one is an asterisk there's an example here
|
|
where we're echoing fruits using the subscript of an at we get back the four four elements
|
|
apple pair grape and banana we get them back in order now the difference between the at sign
|
|
and the asterisk is only apparent when you use the expression in double quotes and only when the
|
|
thing you're using it with cares about about the outcome if you use an asterisk the array elements
|
|
are returned as a single word and they're separated by whatever the first character of the
|
|
IFS variable is we looked at this in an earlier episode i don't remember what number it was i didn't
|
|
make an over but the ifs or IFS variable defines it's the interfield separator and it's usually
|
|
space unless you fiddle with it so you're going to get back the list of things apple pair grape
|
|
and banana in that particular instance but they're all going to be stuck together in one word
|
|
that is as if they were in one string if you use the at sign the array elements are returned as
|
|
a list of separate words and this thing about words here is a little bit odd but i've
|
|
gone an example coming up it's a downloadable one which attempts to demonstrate what this actually
|
|
means and it's really relevant when you are expanding an array in a loop so the downloadable script
|
|
is called bash16 underscore ex1.sh there's only one one script in this associated with this show
|
|
this time and it does some stuff and it uses the ever beloved user share dict words to generate
|
|
random words i've listed it in the notes and i'll just go through the the components of it
|
|
first of all we declare an array the array is an associate no it's not it's an index to array
|
|
so we're using a hyphen lowercase a and we are calling it words and we populate this array
|
|
in a for loop so we've got four word that's the variable it's going to be receiving
|
|
each individual thing for word in and then we've got a command substitution which is
|
|
sort of stuff i've been doing in previous examples gripping stuff out of user share dict words
|
|
when this case i'm gripping out everything that's not a capitalized word and it's not
|
|
a possessive i've talked about this before so i won't go into huge detail that is being
|
|
piped to the shuff command with the argument the option hyphen n with the number five so that
|
|
all that does is to randomly pick five words out of what's being returned by the grip so after
|
|
that closed square bracket we've got a semicolon and the do then what's happening is words the array
|
|
words is being appended to so it's words plus equals open parenthesis and then in quotes
|
|
we have this double quotes i should say dollar word so every time around the loop a word is being
|
|
added to the array and there's the done part of the loop so that's it that's loop that's
|
|
chunking through this list of five words and adding them to the array this is not the best way to
|
|
initialize an array i should say but we haven't looked at better ways yet then the next bit is a loop
|
|
which uses the asterisk as the index when it expands the array so we echo the fact that we're
|
|
doing this now we've got another full loop four word in and then in double quotes we've got dollar
|
|
open curly bracket words that array name a square open square bracket asterisk closed square bracket
|
|
close curly bracket double quote that's a quoted reference to the whole array but it's using the
|
|
asterisk as we said before that's followed by semicolon and do i like to stick the two on the same
|
|
line we echo the words and we get back then the next one next case is a another full loop doing
|
|
just about exactly the same thing except that it's using an an at sign as the index so i won't
|
|
explain it any more than that now when it's run it comes back with the list of five random words
|
|
and i've run it and put the results into the notes and you you get the the message using and then
|
|
the the format that's using what's using the asterisk or the at sign and then you get the five words
|
|
in the case we use an asterisk the words are written out on one line and that's because the loop
|
|
went round only once because the the variable word was filled with all four elements of the array
|
|
which were to then print it out the loop the echo and the loop print it out the other one which
|
|
uses an at gets back each word each element of the array into the variable word each time around
|
|
the loop and it it it errates five times so it gets back the same it's the same array that we're
|
|
looking at the same set of five words but it gets them one at a time so it calls echo five times
|
|
so they come out one per line for five hopefully that there's some some things in that script
|
|
that you might find useful it doesn't it anything useful really but it demonstrates the difference
|
|
between these forms i think it's quite important took me a long while to fully understand what
|
|
this meant so i've tried to condense the meaning into this script for you to to take away we leave it
|
|
there then and carry on looking at this business of accessing railaments in the next episode hopefully
|
|
you found that useful and we'll be back for the next one bye bye
|
|
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'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 hecka public radio was found
|
|
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's show is
|
|
released on the creative comments attribution share a like three dot org license
|