Episode: 2756
Title: HPR2756: Bash Tips - 20
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr2756/hpr2756.mp3
Transcribed: 2025-10-19 16:23:40

---

This is an HBR episode 2007-156 entitled Bashtip, 20, and in part of the series Bash-Cripting.
It is hosted by Dave Morris and in about 33 minutes long and Karina next visit flag.
The summary is deleting a range, positional and special parameters in Bash.
This episode of HPR is brought to you by archive.org.
Support universal access to all knowledge by heading over to archive.org forward slash donate.
Hello everybody.
This is Dave Morris for Hacker Public Radio.
Now when I finished my last episode in the Bashtip series I said I was going to have a bit of a break.
But it's a have had a small break but not as much as I planned.
And the reason for doing that was because I suddenly realized I'd forgotten something from the topic of arrays in Bash.
So I thought I'd put together a show just filling in that gap.
Tell you what it is in a minute and would add in another topic just to fill things out a bit.
So this is sort of supplementary to the Bash arrays business and I've called it tidying loose in.
So I need to tell you how to delete arrays and bits of arrays and stuff.
So that's what I'm going to talk about.
And I also have avoided, not deliberately really, avoided talking much about the positional and special parameters in Bash.
That's the ones we've seen in passing, which we call dollar one, dollar two, things like dollar hash and so forth.
I'm going to cover a few of them in this episode to sort of fill in some of the holes that exist.
And while I'm about it, I'm just going to mention the titles.
The titles of these shows used to be silly, quite deliberately silly.
And I stopped doing that come about by episode 14.
I thought the joke was getting a bit tired and never had any feedback.
So I assumed that it was universally derided perhaps or ignored.
Anyway, I think a few people missed them because I've seen a few slightly more positive comments since then.
And a certain HBR colleague was found vandalising my new style titles as they were being posted.
I won't say who that is.
So I've started adding them inside the notes of the older shows and I'm adding one here.
I went back and added some to the shows that I've already got uploaded.
So this episode's homage to silliness is some collateral bash tips, which we will assume that that's what this episode is called.
Okay, let's get to business.
It's the unset command that we need to look at.
This is a built-in command that originated before bash in the days of the Born Shell.
And you can use it to remove variables, arrays, parts of arrays or functions.
The command syntax is fairly simple.
It just consists of the word unset, followed by one or more, I think, of three options.
And the name of a variable or functional one.
Now, it's the name of the thing and it's not the thing substituted.
So it doesn't have a dollar sign in front of it.
The other thing about unset is that if you try and unset something that doesn't exist, then it's just ignored.
It doesn't cause your script to hold or anything like that.
So let's look briefly at the options.
I'm not going to go into a lot of detail on them here.
Really them from it for other shows down the road.
So the hyphen v option simply means that the name or list of names that follow unset,
refer to shell variables.
So I've got a little example here where a variable fruit is set to the name of a fruit.
It's suddenly had a hankering for certain fruit that you can tend to find only in the far east rambutan.
Great, delicious thing.
Anyway, fruit equals rambutan, then echo fruit equals fruit is then dollar fruit.
And you get back fruit is rambutan.
If you do unset hyphen v fruit and then do that echo again, then you just get back fruit is.
So a variable that's been unset in that way has been completely removed.
And it's not the same as setting the variable to null.
So there's another little snippet of code here which demonstrates that.
This time I'm setting fruit to another fruit or rather miss mango steam, glorious thing.
And I'm using an if statement afterwards that test to see whether the fruit variable exists or not.
And I'm using the slightly confusing hyphen v and the name of the variable inside double square brackets.
You'll remember that that returns true if the shell variable named in there exists and has been assigned a value and false otherwise.
A value also includes null.
It exists with the null value.
So I get back the answer.
It's just the same statement all on one line, just repeated several times it.
And get back the answer exists, not surprisingly, just created it.
Then I do fruit equals nothing.
That's how you set it to null.
Do the if test again and get back the answer exists.
Then if you do unset hyphen v fruit, run that if a third time you get back the answer doesn't exist.
So that's just to prove the point about existence and whether it's null or not.
I've been slightly confused about that in the past so I thought in case you are I would just explain a little bit.
If you use the hyphen f option then the names that are given after unset referred to shell function and these are removed.
I'm not going to say much more about this because we haven't really looked at functions in a formal way.
But I plan to do so before too long.
If you give no option at all then unset will check to see what each name actually is.
If it's a variable then it's removed.
And if it doesn't exist as a variable but it's a function then that is removed.
So you need to be a little bit careful if you're doing this because you might type it wrong and accidentally name a function
that has a similar name to the variable.
Pretty unlikely out of thought but just be aware.
You can run Bash in a strict POSIX mode in which it's defined that functions can only be removed if the hyphen f option is given.
So that's the sort of thing that POSIX tends to do. It tends to tighten up on some of these slightly more relaxed areas.
The final one is hyphen N and this is for removing variables which have the name ref option set.
Now we haven't really mentioned that so far.
We're going to look at that as we look at functions most likely.
I haven't quite planned those shows out but I've definitely got it on the list to cover.
Name ref is a really nice feature.
I think that I definitely want to talk about and explain.
So a couple more things if a variable has been declared explicitly and has been marked as read only.
We looked in episode 19, the last one, at using declare hyphen R or the alias for that which is read only and creating variables that way.
If you try and unset them you will not be allowed to do so.
There's no way of deleting them in fact other than closing down the shell in which you create.
I wanted to just hand my home the issue of putting a dollar in front of the name after the unset command.
So I've got a little example code here and I've got two variables.
One is A and its contents are the letter B. So I say A to quote B.
Then I said second variable B to some string actually use contents variable B is my string.
So then echo these two things with an expression that says a string that says A equals dollar A, B equals dollar B.
And you get back A equals B and then B equals contents of variable B.
So we've got these two variables set up this way.
Now if you mistakenly typed unset dollar A which you know you shouldn't do at all but you know we all make mistakes.
Then if you run the echo again you would get back the answer A equals B and B equals nothing.
So in other words dollar A has been substituted to return the single letter B and the unset was operated on that B
and has deleted the variable B. I suppose that could be useful in some context but I think it's more likely to cause confusion.
So it's another reason why you really should not do that.
So hopefully you'll bear that in mind when and if you come turn to do this sort of stuff.
So let's get to the array part of this.
I think this was an addition. Yeah it must have been because unset came to existence before arrays were added.
It came before bash itself.
So you can unset an array.
So unset the name of the array and you'll delete it. The whole array will vanish.
No dollar sign remember. You'll also use array square brackets with an asterisk in them or with an at sign.
No dollar and no need for the curly brackets. That's not ambiguous.
And you can remove individual elements of an array as well by using the name of the array and some subscript.
So the way I've written these out in the notes here is the sort of syntax diagram that you'll see in the documentation.
There's no actual value. You couldn't you couldn't necessarily type these in their sort of generic descriptions of how you do it.
And I'll explain why I just said that in a moment.
So if you're unsetting an array element then the subscript must be numeric or an expression which returns a num if you're dealing with an index array.
And if it's an associative array then subscript needs to be a string or an expression returning a string.
And you need to quote that variable if it's it's going to return something that contains spaces.
And the index for an index to array can be negative as we found earlier on in this the bash array shows and the element that's going to get removed is relative to the end of the array.
Now when you do this sort of work using shell check to check what you're doing and I've mentioned shell tech it's a script checking tool which is which will check your bash scripts.
It advises that when a subscripted arrays are used with unset and that includes the ones with square bracket asterisk or square bracket at sign they whole thing be quoted to avoid problems with glob expansion.
And I've done that in the examples that I've got in the episode you can probably you can often get away with it but it's the sort of case where scripts working fine and then you make some change to it not realizing that that there's a potential pit for waiting to to catch you the shell check thing helps to avoid that type of thing.
So I've got an example which is called which you download of course bash 20 underscore EX1.sh and in it I'm trying to demonstrate array element deletions sort of things that it does.
It's a long script doesn't contain anything very world-shattering and I'm hopeful that when you go to look at it you'll see that it's pretty self-evident what it will do.
So when you use random variable to select things select an index out of the array for example and I'm seeding it first of all just to make sure you get a different random sequence every time you call it.
I'm setting it to the result of a command substitution using date plus percent capital N. That returns the current nanosecond counter from the clock on your machine.
So you get a nice multi-digit integer number that that should ensure that random is seeded from it with a good starting point.
So let's look at indexed arrays. So I'm declaring an indexed array which I'm calling I a double R I array and then I'm populating it with map file.
And map file is using a one of these process substitution things which calls print F with the argument percent S backslash N and it's getting a brace expansion with the letters A to C in the first pair of braces and D to F in the second.
So we'll produce the pairs of letters A D A E and set it up to C F so that will simply create that number of elements in the array.
The script echoes the number of elements that it actually got and then it uses declare hyphen P to print out that so you can see what it produces.
And it's always going to be the same. So you get nine elements it's there's an example of how it's run in the notes and you get element zero is A D element one is A E et cetera et cetera.
So the next thing is to choose a random element. So to do that I simply create a variable called in which is set to the arithmetic expression using random
the mod operator percent and on the right hand side of that is the number of elements in the array which which is use the expression dollar open curly bracket hash I a double
where brackets a stress close curly bracket so that will produce a random number between zero and nine then the echo that follows echoes element and whatever that number is to be
removed and it reports what its contents are so you'll see that in the in the notes here the script then reports the length of the array now that one element has been removed
and lo and behold it's reduced down to eight elements and then uses it uses declare hyphen P on the array and it prints out the contents which you will see now
consists of one less element it's it's not world-shattering stuff it's pretty damn obvious what's going on here.
So moving on to the associative array and associative array I've got one called a array a a double.
It really must come with better names and that's declared with the hyphen capital A.
Now in this particular case I am initializing this array in a for loop and I'm using the contents of the index array to pop it this up but there's a whole.
So my for loop begins at zero and goes up to the number of elements in the array but there's there's going to be a hole in this array where there's a gap between one index and the next.
So I've actually used in double square brackets the hyphen V thing that checks to see whether given element exists or not and it only adds to the associative array if the element exists.
So the key for the index for the associative array is the contents of the index array so it's a a a a d e in or so.
And the contents of that element is going to be the number of the the element in the index sounds a lot more confusing when I say it that way than it really hopefully it will be because when you look at the output.
So I report back the length of the associative array which is eight remember the array we just built it from had been chopped and had one element removed and it reports back the keys using the expression we looked at earlier on returns keys of associative arrays they come back in an arbitrary order though.
Then I go through in a loop through these keys and print them out but what I've done here is I've echoed the keys I've actually echoed the keys by using the contents of the index to raise bit for cheap and I've sorted them so the you will get from that loop the array name square brackets a d equals zero then a f equals one a equals one I should say a f equals two.
And so on and so forth so you can actually see without using declare a hyphen p what's in this array so then declare an array an index rate called keys and I fill it with the keys from the associative array using a print f then the whole point of doing this was so that I could then use another random thing to generate a random key and
delete that element so that's reduced the length down to seven and final thing that script does is to print out using declare hyphen p the contents of the associative seems to have a complicated thing now I look at it considering where it is but hopefully you'll find that useful.
That's all I'm going to say about arrays and onset let's look at the positional parameters these are the shells command line arguments as it says in the new bash manual.
We've seen these in all the various shows that have been done to talk about bash scripting they're denoted by numbers starting at one so dollar one means parameter one.
Now you can create these at the time the shells invoked but it's pretty unusual to do that it's more likely that you'll see them being used in scripts.
When a shell script invoked any positional parameters core you know xyz your script and they put after a bcd and these are these are the arguments for the script and they're going to be placed into dollar one dollar two dollar three etc.
So in generic terms the positional parameters are referred to as dollar n where n is number starting from one or you can write it as dollar open curly bracket n close curly.
You need to use the one would be curly brackets or braces if the number after the dollar is ten or above so bash can only parse the case where there's a single digit following the dollar.
You know there's various contexts where it's going to be confused anyone so might be good idea to do that all the time I must admit I never do.
I just add them in there's obviously ambiguity or if I'm trying to access parameter ten or twelve or whatever.
And you can't assign to these things because the variable name is actually a number so in order to do it you'd have to be able to type something like one equals forty two and that makes no sense it's not allowed.
There are ways in which you can you can set them right now in fact there's a set command now the set command is massively complex does everything I think I've touched on it before I can't remember.
But one of its features is it allows the positional parameters to be cleared or redefined so you use this feature of it and I'll touch on other capabilities of set as I go through these various shows.
I'm not going to talk about any more today to get it to set the positional or clear or set the position parameters you type set space two hyphons space and then a list of arguments.
And that clears the positional parameter parameters and if their arguments provided it's optional it puts them into the parameters.
There's also a version followed by single hyphen and an optional list of arguments and if there are arguments then they replace the positional parameters but if no arguments are given then the positional parameters remain unchanged.
So set followed by single hyphen doesn't clear if there's no arguments nothing happens if you give it arguments they will replace the positional parameters the exist or it's weird I find this weird anyway but it's really useful.
The other one is the other one is there's a command called shift which is a born shell building command from from before bash.
And what it does is to shift the positional parameters to the left it consists this index is shift followed by an optional number and if that number is emitted then it's assumed to be one.
The positional parameters from n this is this is the explanation part works from the documentation I don't find this useful anyway the positional parameters from n plus one onwards are renamed to dollar one.
If the positional parameters are haggis neeps tatties it was burns night when I was writing points somewhere around that where we the scots eat haggis neeps and tatties.
Anyway if that's your three parameters so dollar one is haggis dollar two is neeps dollar three is tatties the command shift two will result in haggis neeps get falling off and the single parameter being tatties which will now be in dollar one.
It's an error if you try and shift more places than there are parameters and the n to the shift the number after the shift cannot be negative.
If you make an error then you get a non zero status back but the positional parameters are not changed.
I've got an example or some little snippets that are coming up shortly to demonstrate on this but I want to discuss a few of the special parameters before I get to that.
Now a number of these are related to the positional parameters and we'll look at these preferentially just now.
The GNU bash manual contains more detail than I've actually shown in the notes I've put a sort of modified transcript of what it says in the manual here so you've got it in one place.
So let's look at these parameters.
The first one is the asterisk so you'd normally write this as dollar asterisk and what this does is expands to the positional parameters starting from one.
And if you don't put it in double quotes each parameter expands to a separate word when you put it in double quotes you get a string formed by concatenating each of the positional parameters separated by the delimiter inside the IFS.
The IFS parameter, the IFS variable I should say.
So this is where the concept of dollar an in quotes dollar open curly bracket array open square brackets asterisk close square brackets close curly brackets close quotes which we've been looking at throughout the bash array stuff.
I think this one must have come before the array yet well certainly for right before the array and that's why the arrays idea has is using similar thing.
Next one is the at sign and you would normally write that as dollar at and that expands the position parameters as well starting from one and if the expressions in double quotes then you get back a list of quoted words.
And that's similar to the thing where you put an array name followed by square brackets and an at sign and the effects that you get there and I've discussed this on several occasions so I won't go into any more detail.
Third one is the hash mark dollar hash means the number of positional parameters as a decimal number.
So you will often see if tests being done that do things like if dollar hash is not two or something because because then then produce an error because your your script requires two arguments and it hasn't got them.
Final one is zero so dollar zero this expands to the name of the shell or the shell script.
I'll explain the business about creating a shell and fiddling with it in a moment.
But shell script I certainly find some more useful context in which to do this and we look at shell scripts loads of times so it's no big deal.
So it applies a lot of this also applies to functions shell functions but we're going to deal with them in a few shows down the road.
So what I've done here is I have put together a couple of examples.
The first one is just what I did is I put together a whole list of commands a typed list of commands at a terminal and captured them in their output to demonstrate things.
I've split them up into little groups so I can then explain each bit.
It's not a thing you can download because well we'll see why in a moment.
The second one is downloadable script.
Let's start on me the snippets.
So it starts with a dollar prompt and at the dollar prompt slash bin slash bash has been typed followed by space hyphen s and then the words hacker public radio.
So what's happening there is a new shell is being created the hyphen s option runs it interactively and allows arguments.
You then get back a prompt prompt doesn't look any different from the first one but it is you're now in a sub shell and there I echo dollar zero.
Well dollar zero if you recall it's the name of the shell or the shell script and I get back as an answer slash bin slash bash.
So we invoked bin slash bin slash bash and that's what's in dollar zero.
Then echo dollar hash mark get back three because there were those variables those three arguments which are now in the three positional parameters and so the answer is three.
Next one is echo dollar at sign and we get back the three arguments hacker public radio.
Now the next thing I'm doing is to set the positional parameters using the set command.
So what I've done here is set space hyphen space dollar at space is space cool.
So what that will do is it will take all of the arguments as the positional parameters that we saw before the hacker public radio will expand them and then append is cool on the end of it.
So if you then type echo dollar as dollar hash you get back five five arguments now if you echo the arguments using dollar at you get hacker public radio is cool.
Now if we the next snippet we use shift space to and echo the result we get back radio is cool that shifted hacker public off the end and into oblivion.
Now I created a very very simple little script which I didn't put the creation of it into this example but it's in slash TMP slash test if you don't know slash TMP is the place where you can put temporary files and they get deleted often.
You log out I think it is depends there are various rules that you can control which will change the convention is that they are deleted when you log out.
So anyway this TMP test file consists of hash exclamation mark slash bin slash bash so that's hash bang which defines what what that's what you do at the start of script in order to say what script language it is and what's going to execute the content then there's an echo dollar hash and an echo dollar at and then exit.
The thing I haven't noted here is that I've had to make this file executable in order to make it work.
So if you simply type slash TMP slash test and then give it the three words which in my case were rice millet and wheat then the script echoes back three because of three arguments given to it and it reports them rice millet wheat.
So you can see the point of this was to show that running a script takes its own set of arguments puts them in dollar one dollar two dollar three and so forth and when the script exits the positional parameters in that environment still intact and demonstrate that by echo dollar at and I still get back radio is cool.
So the last thing in this particular snippet is exit and that terminates the shell that we opened up at the beginning.
The idea was that you could maybe have a shot at doing this yourself to see sort of things that can be done.
So the final thing is a downloadable script bash20ex2.sh this is a very simple script and it's just to demonstrate positional parameters.
So in it there's a test if followed by double square brackets dollar hash hyphen ne2 close double square brackets semicolon then.
So that is testing to see whether the number of arguments given to this script is to and if it's not then it's narrow and we want to exit.
So the body of the if is echo in and in double quotes usage colon dollar zero word space count close double quotes.
So remember dollar zero here is the name of the script itself. I didn't actually demonstrate that if you want to download it play with it you're able to see that that work.
So within the after the the fi of the end of the statement set two variables word is equal to dollar one and count is equal to dollar two.
So then all I do is to take the word that first parameter and the count and I just simply repeat the word count time.
And that's done simply by a for loop which starts up one and increments variable I up to the value of count.
And for each instance it echoes the word in double quotes dollar word and it uses echo hyphen end to do this.
So there's no new line after each instance of the word then the loop ends and there's a further echo to produce a new line on the end of the concatenation of the words.
So when you run this and in this particular case I ran it as slash bash 20 underscore x to dot s h goodbye three and it generates the following output which is goodbye goodbye goodbye.
I thought it's been really clever there. That's the end of this particular episode and we'll call it quits there. Okay, I hope you found that useful. 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 founded by the digital dog 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.
You
