Episode: 2739 Title: HPR2739: Bash Tips - 19 Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2739/hpr2739.mp3 Transcribed: 2025-10-19 16:04:10 --- This episode of HBR is brought to you by Ananasthost.com, get 15% discount on all shared hosting with the offer code HBR15, that's HBR15, better web hosting that's honest and fair at Ananasthost.com. Hello everybody, this is Dave Morris for Hacker Public Radio. Today I'm doing bash tips number 19 and I'm still talking about a raise and this is part 4 but it's the last in the group about a raise. Do I hear a sigh of relief? So in the last show we looked at parameter expansion in the context of a raise. There's more that could be said about that but I think I'll probably not say any more, unless I'm called to do so in the future. But in this episode I want to look at the command we've already seen in brief called declare and it's also got a synonym which is type set and then there's some other related commands read only and local and there's a couple more that allow you to load data into a raise which are called map file with the synonym read array and read which we've seen in passing several times. So declare or type set, it's there because the synonym is there because that's what it's called in the corn shell and so it was been added to bash for that reason. So we've seen how you use declare to create a raise and so forth but it's used generically to create variables and to give them attributes. There are a whole list of options to declare but rather than going through them all which I don't think I need to do really, I thought I'd just spend a little bit of time looking at the ones that relate to a raise partly because I found them quite interesting to discover a few euro two back when I first started playing around of the raise. Now there are, this command is a little odd, there's not many commands do this, the options usually consist of a hyphen followed by a single letter, it's quite common in Unix to do it that way but some of them you can reverse their effect by replacing the hyphen with the plus sign which is all fine and nice and stuff, it's a bit confusing because there's not much else that you can do that with. Anyway, let's start with an option you probably not going to use very much but I think it's quite cool so I thought I'd mention it, it's the hyphen i, lowercase i option, what that does is make the variable you're declaring which would raise what we're thinking about here, behaviors if it's an integer only an integer and whenever you assign anything to it an arithmetic evaluation is performed as if it was inside the double parentheses which we've talked about in this series so I thought the easiest way to explain this was to put together a downloadable script which is called bash19 underscoreex1.sh and it shows what you can do with an array declared this way so just to go through it briefly because I think it's pretty well self-documenting there's little comments in it. I'm declaring two arrays, one is called int i and ts and it's declared with hyphen a and then hyphen i and the name int's, int's or integers. There's not to declare another one hyphen a and I've called the array norm because it's just an ordinary array indexed arrays in both cases. So I put into ints a couple of values in by by putting an an assignment statement ints equals and then open parenthesis and a couple of things being added there and the two things I'm adding are a couple of expressions in quote so they're quoted a strings effectively but they're numeric expressions within them so we've got 38% seven so it's using the modulo operator which divides by seven and gives you the remainder and then the next one is in quotes 38 slash seven which is dividing, doing integers division on 38 and the norm array gets the same stuff then for each of the arrays I add a string to the end of it so I've put the string jellyfish onto the end of each one using the append operator so the plus equals to append another value to the end of the array just so you can see what the effects are then the script echoes the contents of ints and the contents of norm to show you what you get well within ints you get the values three five and zero because the value of 38 mod seven is three and 38 divided by seven is five and then the value of the string jellyfish because it's not numeric is treated to zero anything that's not numeric any string that's not numeric is regarded as a zero which seems sensible I think we covered this reasonably comprehensively in when we were talking about arithmetic expressions and stuff when you come to look at the contents of the array norm then it's just got the string 38 space percent space seven in one element 38 space slash base seven in the next and jellyfish in the last one so that's all really it's pretty pretty straightforward stuff but quite useful I would say then we come to the hyphen L and the hyphen U both lowercase letters these options force any alphabetic characters that you store in this array it forces them to lowercase in the case of hyphen L or uppercase in the case of hyphen U so obviously when you declare these things you don't need to declare one of these at a time so this is mildly useful I don't I've never used it myself I don't see a use for it personally there you go the last one last option I want to mention is hyphen lowercase R now what this does is it makes whatever you declare read only so when you are declaring you also have to initialize them because you can't change their contents at all afterwards so it's a way of declaring constants and I've got an example that sets a simple variable not on array in this case but the same applies to arrays I've declared hyphen I R you can concatenate these options by the way so the I means it's an integer the R means it's read only and I've called it sixth prime and I set it to 13 of course I use the sixth prime then I try and set sixth prime to 17 I get back the the error message bash call on sixth prime call on read only variable now you think well can I turn off the read only capability so try to declare plus lowercase R sixth prime which by rights should turn off the read only thing but because it's read only I guess the logic is you can't do it and you get back an error message just in passing there is a command which is which comes from the born shell which is equivalent to declare hyphen R and it is read only so it takes some of the options that declare takes and it lets you create arrays and variables and stuff which I read only so it's doing the same thing it's just that bash is a sort of a blend of the older born shell so I call born again shell of course I think I've said this before the next command is the local command it takes the same options and types of arguments as declare but you're only allowed to use it within a function so if you're if you're creating a function declaring a function then you can use the local command to create variables and stuff within it now I have demonstrated this when I've talked in other shows about creating functions but I've in this particular sub-series I haven't really explained functions in detail so I'll leave the rest of the use of local to that when I get to that but the point of it is that it makes the variables that you declare local to the function so they work within the function but as soon as the function exits they vanish so it's like other programming languages now we move on to what I think is a very very useful command which I didn't know about until maybe earlier this year I think never used it much myself but now I've discovered it and understood it find it extremely useful and it's map file which has the synonym read array so what this does is it reads lines from standard input and puts them in an indexed array it can also read from a file descriptor which is a way of connecting bits of a script to a file but I haven't looked at this yet I plan to talk about this in an upcoming show it's on the to-do list anyway so I'll leave that I won't talk about it here just to mention that it exists so I've prepared a command syntax diagram he thing which shows all the options and what you can follow them with which I've grabbed from the GNU bash manual included in the long notes here and all of the options and arguments are optional in fact I also made a table of all of these options where I explain what they do just to talk about them briefly you can change what delimiter terminates each input line in other words define a different end of line bit like the way you can do stuff like that in orc you can control how many and that's with the the hyphen d delimiter option you can define how many lines are to be read so if you're offering map file a file you want to read the first few lines from it then you can control that if that is with the hyphen n option with a numerical count if the count is zero then all the lines are are read and if the hyphen n option is not I used it all then it reads the entirety of the file you can change where the lines are written into your array because normally they will clear the array and we'll start at zero to write values in and that's done with hyphen capital O and then the numerical origin that you want to write to you can if you wish skip a number of lines from your data source from your file with hyphen lowercase s and then a number count and here's the thing I think it's quite nice the hyphen t option she doesn't have an parameter to it you can remove whatever the the delimiter is from each line so if you're reading stuff separated by new lines which is a pretty common scenario using hyphen t will throw away the new line so when you come to list out contents your array you don't end up with new lines after each element the hyphen lowercase u is followed by a file descriptor but I'll not talk about that for now but it changes what what source the map file reads from rather than from standard input then there are two things that I have played around with but I don't know how useful they're going to be there's hyphen capital C followed by a callback a callback is either an expression or a function which is going to be called by the map file command every time a certain number of lines are read the number of lines is called the quantum and that's to find by the next option which is hyphen lowercase c and a number so if you don't have the lowercase c then it's every 5,000 lines that you've read in but you can change that I've got an example coming up to demonstrate this so the final argument to the map file command is the name of the array that's where the lines can be written you need to have created the array first if you don't specify an array then there's a built-in array called map file in uppercase into which stuff will be written it's quite an interesting thing that when the callback is invoked whether it be a function or whatever then it is given two values the first where is the index of the next array element that's going to be assigned and then the line that's going to be assigned to it the callback functional expression is evaluated after the line is read but before the array element is assigned so you could use that to filter stuff out if you really wanted to you could do some quite clever stuff in there I haven't experimented with that very much but I do have an example of using it coming up so there's a downloadable script that demonstrates some of the features of map file and that's bash 19 underscore EX2 which is moderately long actually now I come to look at it a bit carried away but I just threw in a bunch of things that you could do to fill an array using map file and I've alluded to this along the way because I've been filling arrays in loops and it's not necessarily the best way of doing it so in my script I've got I'm declaring an index array called map and then call map file with the hyphen t option and the array name map and I'm feeding it through a redirection so it's using a less than sign to redirect from the next thing and I'm using one of these process substitution things which is a less than sign and then commands in parentheses and what I've got in the parentheses is a for loop which goes for i in and then a brace expansion of 1 to 10 so it's it's going to iterate through values 1 to 10 setting i to each one and then semicolon do then the the actual meat of this loop is an echo echoing dollar random being the uppercase variable name which gives you a different random number each time you call it semicolon done and that's the closed parentheses so what that will do is it will fill the array with 10 random numbers and it because we're using echo in the loop it will be generating a new line but map file needs the new line in order to tell where one line ends and the next begins but I've told map file to throw it away when it stores so then use an echo to print out the contents of this map array using the syntax for printout and entire array using the asterisk as the index and you you can see that later on in the in the notes just I just run it and put the result just a list of 10 random numbers on one line next thing define a string just put in a simple variable called words and what I did was I put few lines from words worth poem in there where all the spaces had been replaced by underscores really just to demonstrate how you could use alternative delimitors so I wondered lonely as a cloud and all that stuff is in there then the map file command that plays with that uses hyphen lowercase d and follows that with an underscore so the delimiter is the underscore between each word and I use underscure hyphen t to strip off the underscores and I put it into an array called dafts d a double f s because it's about daftedals so I forgot to say I declared it before so what that does is another process substitution which simply echoes the string called words without a trailing new line uses echo hyphen in to do so that will load up map using map file that will load up dafts with all of these words one per element and will have removed the underscores that's doing it and there you go and now echo the contents out again and you can see after the script there's some example output from it where it prints out the words of the poem on online the final demonstration in this script is to declare another index array which I call big in this case because it's going to contain many contents many elements well hundreds but then I use map file with hyphen t located t that is and then hyphen capital c and following capital c is a print f so the print f statement has a format which consists of percent zero to d space percent s backslash n and what that will do is it it will expect two arguments first of which it will treat as a number we print it out with two decimal places leading zero and the second one that will just treat as a string so that's all in double quotes then the next option is hyphen locc followed by the number ten so the quantum is going to be ten every ten lines that it gets it will invoke that call back then the name of the array is big we're using the same structure again of a less than sign to redirect and then process substitution less than sign and then bracketed list we're using the ever present printing or extraction of words from user shared dict words this time I've used shuff and ask for 100 words so the final bit of this script simply echoes the contents of the array we should have been seeing stuff going into the array as it as if the the map file was being invoked but I'm printing them out as a while so the first thing that's printed out is the number of elements that we got in this array called big and then the second thing is a for loop which begins setting i to nine and iterating until it reaches the number of elements in the big array and then we're we're incrementing the number by ten to each iteration and inside we're using pretty much the same print f command where we're same format anyway so read it out again it's printing a number and then a string and the the number is coming from the variable i and the string is coming from the array element the i the rail so when you run this you get remember we're getting random words out of it so what I'm seeing on the screen won't necessarily be what you'll see in the notes because I probably probably run them again before I before I write some at the show but there's a list of elements that are going into the array every every tenth element so the first one is zero the first one will be the added theory will be the zero and that won't be shown but then the next one the tenth element will be the one with the index of nine and we get a word out and then the 19th another word and so forth up to word number 99 and the loop does pretty much the same it says there are a hundred elements and it prints out the same stuff so that was just really a demonstration of what you can do with map file personally I now use map file to load load arrays pretty much all the time and I'm doing this type of thing so I find it amazing useful hope you feel the same way about it so the final bit of this show is to mention the read command we've used read loads loads time and all sorts of examples in this bash tip series we haven't looked at the option which is hyphen lock case a followed by a name what that does is to load an array and the array is named with whatever you put instead of name but because read reads one line at a time then we're assuming that all of the words that are going to the array are all on that on on a line and more to the point the array is if you keep nominating the same array then the array will be overwritten each time read is called with the same array so if you were doing this in a loop you'd have to be very careful doing for that reason all of the words to go into the array need to be on the one line and the work the the words on the line are split up using the word splitting process that we described in episode 2045 that was we were talking about the whole subject of expansion and word splitting is one of the things that happens when a command or a file spec is being expanded and it was described in so I've created a third downloadable script bash 19 underscore EX3.sh which has a little demonstration of the use of read with this particular option I'll talk more about the other options later on I think I don't have a particular slot to do this but I'll talk about them in passing I think as I go forward with this series so in this script we start by declaring an index to array which in this case I've called read test now I thought there are ways in which you could present a read with a single line but read is normally reading from standard in which means you would have to type this stuff it's not not a straightforward thing to put it within the script but it is possible but we haven't really covered what this would require yet so I'm not doing it the way that you might do if you're doing this for real I've just done a sort of demonstration of generating some data on standard in and poking it into an array the read consists of read space hyphen lowercase r that's the thing that takes away the meta status of backslash things like backslash n and so forth basically ignores them in the it doesn't give them their special meaning and that's followed by space hyphen lowercase a and then read test is the name of the array so that's the read command we want to do we're going to read a line and put it into read test which is an array so this one is using the same stuff as we've been using in previous examples in this episode it's using a less than sign to redirect some stuff from a data source and the data source is another one of these process substitution less than sign open parenthesis some stuff inside the parenthesis close parenthesis and what we have inside this inside these parenthesis is a for loop we're setting for c in and then we're using a double brace expansion the first brace expansion is capital A to capital J that's first 10 that's the alphabet of a case then in the next set of braces 1 dot dot three so you'll recall from when we talked about brace expansion that this will generate sequences like a 1 a 2 a 3 b 1 b 2 b 3 etc each time round this loop not reading out the minute details of this we echo the contents of dollar c the variable c but we do it with echo hyphen n which suppresses the new line because we want just one line to come out this thing okay so this will generate this list of a 1 a 2 a 3 stuff which will then be fed into the array so to demonstrate what actually happens simply echo out the number of elements that are in the array which will be 30 it's 10 times 3 is 30 and then echo out the contents so as I said we get a 1 a 2 a 3 b 1 b 2 b 3 c 1 c 2 c 3 etc add north here so hopefully that demonstrates the purpose of this quite well so with that said that is the end of this particular episode and of the sub sub sub section talking about arrays and i'm going to give the bash tips series a little bit of a rest now for a for a month or two well i do something else because you probably bored sick of it and i could do the bit of a change as well so but i'll come back to it in due course okay then 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 hbrlist snare 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 dot pound and the infonomicon computer club and it's part of the binary revolution at binwreff.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 light 3.0 license