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