 Well, it's that time of the week again. It's time for chitchat across the pond. This is episode number 763 for March 25th 2023, and I'm your host Allison Sheridan. This week our guest is Bart Bouchotte's with programming by stealth number 148 and I had a lot of fun this last week Bart Yeah, and this time I can say last week without having to correct myself to last time 50 times in an episode They're not the listeners have noticed how often I do that How long have we been doing bi-weekly a half a decade? At least yeah a decade Actually since I was doing let's talk apple. Oh my god, that is yeah, that's oh my god. Yeah, and I still get it wrong every time So there you go Anyway, we actually did it we actually did it back to back here But before you can start I want to tell the listeners about something why I had so much fun this week The the challenges for 146 and now 147 have been really fun in the in shell scripts And so Ian Lessing in our slack at podview.com slash slack in our PBS channel for programming by stealth posted a link to his solutions in GitHub where he was working on it. It wasn't completed code. He was just working on it and he posted it in there And then I thought well wow that took a lot of courage. I don't want to show it Well, mine's stupid, you know, I'm not done yet. It looks really dumb and you know, I don't want to do that But hey if Ian's got the courage, I'm gonna do it So I posted mine in as a response to his well then Ben Rose came in and he goes well Hey, why don't we have a place where like we can share our homework? And I thought well, that sounds like a good idea But now Barton tried to do that with the PBS gallery a while ago And unfortunately it was just a lot of work to maintain So we went on a hunt and it was also a slightly different problem to be solved because that was about showing off your working web app Whereas this is a bit actually doing the building, right? So you're talking about a place to build together not up not a gallery to show off the end result So it's actually different right? It might eventually be the end result But but it's it work in progress is what you're what we wanted to do And so as we could learn off of each other basically cheat off each other's paper is what we're looking for So I went poking around and I don't remember if somebody told me about it or whether I found it But there's a thing called a github organization now Bart created an organization when we were working on the the book for taming the terminal and doing some automation in there with with Helma and So I knew the the concept but I started digging around into it And it turns out it is the perfect solution as a place for us to share code and be able to see everybody else's code so The way it works is there's there's one repo Inside this organization, and it's called pbs challenges pbs-challenges and the the organization is called pbs-students and You have to be invited to be one of the students and you have to be invited by me now The way you get invited by me is you say how Alson kind be invited and then you get invited That's all you have to do But you do have to have a github account so you have to give me your handle Otherwise, I can't invite you within github and so a working knowledge of get and github is I would think requirement I wonder where they can find that Yeah, I do wonder that I will get back to that in a moment So anyway, once you go in there then once I when I invite you all I have to do is create a folder for you within the repo So there's a folder for Bart That's folder for me a folder for Ian one for Ben one for Dorothy and one for Helma so far I think and so we've got all these different folders in those folders is where you put folders for each challenge So pbs 146 dash whatever you want to call it, you know, maybe keep it organized the way everybody else does so people can find each other stuff So the the thing I had trouble with this Ian actually helped me build it and Ben gave a lot of good feedback, too Is trying to figure out what the structure of this would be the way this works You clone this entire repo and then you have everybody's solution to everybody's check every single challenge So five years from now, this could be a big repo. I don't know whether it gets ungainly at that point I'm not sure what happens. Remember the text file the Linux kernel. Yeah, but gate was designed for the Linux kernel I promise you the Linux kernel is bigger Right right text files, right? They're not gonna be I don't think this is gonna be huge I mean don't put any videos up there, right? I mean, I suppose you could but that would be weird I'm not aware of any challenge. I have even in the vaguest of my imaginations that would involve Giant big video files. Don't do that. Yeah, yeah Yeah, but it looks like it's gonna work pretty well and we've got it built We started to get some people asking about it and here's a great thing about two two people I want to call out by name here Thomas wrote me an email and he said, you know, I've just started listening to programming by stealth and I've really wanted to Understand git so I guess I should try doing this Organization thing you're doing and so that was a great opportunity. I was the guy I'd never talked to before Didn't know he was starting to listen. He's new to the show. So this is great so I pointed him at all of the lessons that you did on Explaining git and again the most popular part of everything we've done is what your series on git We get the most feedback from that. I think yeah, I get it all the time and it is the single Yeah, it is the single most successful thing I think we've ever recorded together is that series on git Yeah, yeah, I think shell scripting is coming along because we're getting a lot of people excited with shell scripting So so anyway, I'm getting directing into that. But another perfect example is Mariana just joined our slack our PBS slack and it was the most wonderful thing I've ever read It was just fabulous. She said she said look, I'm brand new at programming and I'm I'm on PBS 12 and I'm really nervous and feel weird just putting myself out here joining this community because I don't know very much But I know that everything I've read says you have to have a community So I'm here and oh man, everybody just open arms It you know just embraced her immediately going and she even told us she's in her 50 So I loved her even more, right? So she's you know doing this later in her in her life kind of like I am and I don't know everything about that Was great. So the PBS slack is on fire We've got people joining this this organization now We have a place to share our work and I love it and I posted yours by the way from last week in your folder Oh, yeah, that was that was one of the other requirements I put it in the list of requirements was it can't take any of Bart's time because there isn't any We have no time for from Bart and and with the one exception of I think there should be a second owner maybe somebody else becomes the second owner but We could tell I'm happy to be a second owner because that's basically a second pair of keys in case you get looked at at the house, right? Yeah, exactly exactly what I was thinking of us. So right now I've just been and I've learned how to make folders, which is not easy inside github You have to say there is no make a folder. It's make a file and you put slash at the front of it It goes. Oh, you met a folder. Okay. Good. And then you put you so you put slash Bart slash PBS 146 Read me. Well, you could put a file into the folder and it will magically appear So if you make a read me that I'm D and just stick it in a folder and it could just say like this is Bart's folder But I mean at the github level when I'm in the github interface I can't create a folder to put a thing You're right, but you actually you make it all at once. So you you say that the name of my file We see yeah, you say the name of the file is slash Bart slash read me and then Bart existed. That's how I did Yes, yeah, that's a git thing not a github thing Because you'll notice if you have an empty folder and you go to do a git and you're in a git gooey It won't show up on your list of changes. Hmm. It won't show up to be staged Okay. Yeah. Yeah, yeah, yeah I do think one of the fun things about the and I think I said this last week The fun thing about the shell scripting is now I am doing so much from the command line I'm really really getting a kick out of doing it that way. It just it just feels like a more natural place to do it Don't just wait to see what it does your automations And if you know as you get your feet under you here like it really does when you when you have a tool like well, there's loads of them like Alfred and Even text is rounder shell scripts keyboard my store. There's so many these tools hazel. Yeah, they can all ruin shell script And so now you get to marry the gooey with real programming It's quite powerful. I do an awful lot of shell script action stuff in I used to do an automate and yeah, automator I guess I'll do it in workflow. We still can't change over. I still can't You mean in shortcuts, that's the one that's the one so yeah before they bought it. Yeah, they renamed it Yeah, the the other thing when I was talking to Ian He said that he's really digging having a stream deck. Yeah, oh, he was complaining about things I've made him buy and so he's talking about a stream deck and and I said oh So how are you automating things on your stream deck and he said with shell scripts? He says even if I have to call an Apple script inside the shell script. It's a shell script to start with so That's kind of what he's learning. Yeah That's how I do most script is a code to the terminal command OS a script, but anyway, that's yes Yes, anyway, so you people listening you don't have to memorize anything that I told you there will be a link in the show notes to the blog post I wrote that explains this whole thing Yes, excellent. Now we can start Yes, and this episode has not quite gone to plan, but I think that's for the better So not only are we recording a week earlier than usual because We both have lives and it just works out better this way Uh, I had promised you that we would be learning about the The command for putting proper like named arguments minus a or whatever on our shell scripts And how to make them work with the pipe and stuff and I had fully intended to do that So what I was going to do was quickly write my sample solution to the challenge, which I mentally thought was simple kind of is simple um And then I got really stuck like the universe start making sense stuck Like I couldn't make a variable go stuck And figuring out the very very very subtle subtlety of bash that I had walked into with both feet Actually is a really good to remind people that When the world doesn't make sense You are not the first coder to hit this This will happen many times in your coding experience There will be a technical reason You will be frustrated as all heck between Discovering that the world doesn't make sense and finally seeing the light and it will seem like you will never see the light And you will feel I am silly. I'm just not good enough all rubbish It happens everyone one decade two decades. I'd probably still have me in three decades I've been coding. Yeah. How long have you been coding? Uh, we're doing that I'm doing 97 1997 not shell scripts is 97, but I've been coding since 97 It doesn't really matter what language you use It will keep happening. So when it happens to you not if when Don't feel bad. Don't feel there's something wrong with you This is just what happens and you will get to the other end of it and you will end up learning a lot But you'll be quite cranky in between I was going to say now when this happened you were you even headed and calmly said oh, this happens to everybody martin I'm more so than I used to be But not perfectly. I was no buddhist monk Uh, but I did have the common sense after an hour to just sleep on it I had to do a lot better the next day A lot better than always always works Yes, so anyway, I basically figured 10 minutes to do the two sample solutions one for the not bonus one for the bonus And then we'll get stuck into the new content And then it was literally noon today and we're recording today And I hadn't written a word of show notes apart from my two sample solutions that had taken me right up until noon today Uh, but I think there's a lot of meat here. So I've turned this into a popery episode because as well as the thing I hit my head off hard There was also a few other little things That I've kind of been like I need to squeeze these in somewhere I need to find a hook for these little things, but they're too little To be an episode So why don't I hang them with this what I hit my head off? And then we have an episode. It's actually going to be very practical But it wasn't the one I'd planned Okay, okay, which is fine. The one I had the one I had planned will be just as good next time So the first the challenge was to store a an array of breakfast items Or a breakfast menu as an array basically And then to use the select loop to allow the user to choose items for breakfast And you should add an extra option into the list of items for i'm done And just keep asking the user what would you like? What would you like? What would you like until the user says and that is all And to capture the choices So that at the end of the process you can print out and say and here is your breakfast order So you can be a good waiter and read it back And that was the challenge and then for a bonus credit instead of hard coding an array because that's Remember we talked about the concept of a bad smell in software engineering Well data in your code Is one of those bad smells If your script is your data It might be okay for something you've hacked together in five minutes. It's not a good idea for anything serious So you want to separate them out. So the challenge was Make the menu be a text file that you read in And you should ignore empty lines and lines to start with the up close up the pound sign the the standard comment symbol Which is quite realistic because you generally do actually want if you're going to read your data from an external file It's really good for your own sanity to be able to put some comments in Because it will help trust me. So that seemed like a sensible challenge And it literally took me the expected five minutes for the solution to the initial challenge because well, I've been doing this a while as we said So in the zip file, you will find pbs 147 dash challenge solution that sh which is the solution to the basic to the to the true challenge. So Usual to bang line Then we define our menu as an array So menu equals open around bracket pancake space waffle space porridge quite a few other with the space And then at the very end I have orange juice in single quotes because it has the space and if I didn't It would be orange and juice and what orange is a valid breakfast item Juice is a bit nondescript to my liking. I prefer to know what it was you juiced before you gave it to me um, so You know quite by the book then I made an empty array which I named order using the declare keyword so declare minus a for array order and then I Very politely echoed at a menu choose your breakfast and then I used the select loop to loop over The exploded version of my menu. So we learned that you can use dollar open curly name of array open square bracket at symbol close square bracket close curly to effectively Explode your array into a sequence of arguments Effectively right because remember ultimately bashes about commands. So it's effectively a sequence of arguments And we're passing those arguments to our select statement command Now we have orange juice in there So if we didn't quote that exploding syntax Then orange and juice would come out as separate items Even though there were one item in the array they would now come out space separated and they would become two items So in order to make it clear to bash our intention is that it should Honor the spaces we quote the exploding syntax as I'm going to keep calling it So when I when I did my homework, I decided to jump to the challenge part So I didn't actually do the the easy method. I started with an external text file and get getting that Orange and juice separate as one set was really really difficult from an external file That took me Quite a while to figure that one out and I'm not sure I did it the way I should I think I might have done it a hackery way. We'll talk about it when we get to that point though Well, I there are an infinity of correct solutions I would say they're on a spectrum from very elegance to in elegance So I don't know where in the spectrum you land, but if it works, it's still right I'll ask you about it when we get there. Okay So then I have in my loop, you know Uh, basically. Oh, yeah. Sorry. The other subtleties I wanted to be able to say I'm done So we don't just want to loop over the items in the menu We also want to loop over an item that just says done or something, you know Finished or I went with done because it was less typing So That's just another argument So you can just say select item in done and then explode your array And then effectively you're looping over done plus all the elements in your array And I chose to put done first Wait select item in So if you have select item a space b, it's going to select from a and b Yeah So you said done Well, you haven't taught us that that you could do that I guess you just did I was going to say I did implicitly but maybe not explicitly enough because remember it's anything after the a and is a sequence of arguments So you can put any arguments you want there and one of those is when you explode the array You make it into arguments, but there's no reason you can't explode two arrays or so you could have said select item in Pancakes waffles porridge done Yes, yes, you could which is how we did it in last instalments example Okay, okay. That's interesting. All right. I find that a very confusing syntax to look at it that way But okay remember it's all terminal commands so after the word in is just a sequence of arguments And the exploding syntax turns our array into arguments But it doesn't turn them into the only arguments They're just arguments so you can have more before and more after And so you could explode 20 arrays into one select statement if you had 20 arrays, right or mix in a few variables, right? They're just arguments. It's a list of arguments So anyway, select item in done and then our exploded array Do I'm going to intentionally skip over the next time because I want to talk about it later So put a pin in that and then we want to do a check to say well, did they choose done? So the first thing I do is our lovely shortcut syntax where we can use two ampersands to do a lazy and So we start off with the square brackets for doing a conditional. So our condition is item is equal to done And then we say ampersand ampersand break. So because of lazy evaluation The break will only happen if item is done So it's a really short if in front of that No, because remember the and will only execute the second statement of the first statement is true We learned about this shortcut a while ago It's often used for if something goes wrong and do an error or or do an error or whatever So it's lazy evaluation So if the first item is true only then will it will bash try to figure out if the second item is true as well So the square brackets just give you back an exit code of success or fail So if our item is equal to done success Okay, if the first item in the and is success, I have to check the second which is break At which point nothing matters anymore because you've jumped out of the loop Okay, so it's not the double brackets that's making that an if statement. It's the ampersand ampersand Correct. That's making it an if then. Okay. The two square brackets are basically saying give me an exit code for this piece of logic Okay So well, I decided to stick in between those two Thank you your order is and spit back the order right inside of there. So I don't think that would have worked for me Uh, no particular reason you couldn't have you couldn't have that too, right? But anyway, so uh item done Ampersand here's your order Oh, I see what you mean. No, wait There is a way but it would not have been elegant. It would not have made your code better Okay, okay I thought about putting it all outside of this like you did but but it seemed like that was a perfectly good spot It was gonna it was gonna exit right there That's true. Actually, that is another way. So instead of saying break the loop you can go straight to exit Which is just end the script. They're two perfectly valid approaches I still did the break, but I just did the break after I told them what they're meant what they had ordered So how did you make it exit the script completely then? Oh, no, you did a break and then yeah, and the only reason nothing happened after the loop is because you had no more code Okay, so again Pretty much by the book then after so I I do have to exit so I after my pretend my little Short elegant if statement I then order plus equals my number of my item And then I print out added item whatever to your order Now this is the point in the show where you need to jump in and tell me that I was in a bit of an idiot last week Well, we can't call it an idiot, but Actually grumpy says he wants his money back for last week's episode When I started using you can have it back a million times over his zero So in the show notes the way bart did it last week He said you can add to the array saying in this case like order plus equals dollar item And then he said you can also say order plus equals And then use the square bracket syntax to say put it in position one So he was doing he did waffles with the plus equals and then he did pancakes with the square bracket one And his code worked perfectly, but I I was going to be looping through this text file So I needed to keep using plus equals and then you know dollar item Well, it turns out it doesn't work without round brackets around it It just smushes them all together. So I got pancake waffles I didn't get pancakes on one line and waffles on another line when I spit the array back out It was squishing all together Yeah, and that's basically because the syntax that I was supposed to type had the round bracket all along But if you if you leave out the round bracket on the first item you get away with it by default Which are actually doing you say add this string into the array and bash is like well, that's an odd thing to ask for but okay But when you do it the second time You just get your first string gets bigger and then your first string gets bigger again That list that those roundy brackets indicate This is a list that I want to stick into my array and that does make a very big difference So, yeah, that was a typo from last time So the people who have been reading along will not have seen the problem because Thanks to the magic of gate. We have fixed the problem But we're saying it out loud even though it's not written in the show notes Because any of you who were listening last time will have heard the wrong thing And now we've corrected it it was supposed to be there and I actually if they listened last week and read last week They knew it. They they ran into it True. Yes. Yes. I mean if you're recording again quickly enough I think we'll we'll probably have corrected 98% of the people Exactly, exactly Yes, if you're with us in real time, you know, we made this silly mistake that we have now corrected And if you're coming back to this years later, it'll be fine in google Uh We won't need you up the garden pass, but yes, that is kind of important And I know as soon as I did my own challenge solution. It's like, oh, I forgot me brackets last week So anyway, yeah, so I called Bart and I said, hey Bart, you know when you did that plus equals he goes, I know So you already knew what I was calling you about Yep He's kind of slightly cranky with myself because plus equals is really obvious syntax But yeah, the brackets are kind of important. So anyway, I did that So for the most part, there's not really much here to call out Apart from the thing we've already mentioned of sticking the dough in as one of the arguments in the argument list for the select And the other sort of thing that we called out. We did the brackets. Oh, yes I'm the the cheap little avoiding the statement with the ampersand ampersand just a reminder of that But then there's that line. I asked you to stick a pin into So what we haven't really said is Right, so the select loop is lovely, right? It gives you a list of options and they all have a number and if you type in the number next to the option you want then in the code The value of that option is what goes into the variable So dollar item in the case of my code is whatever is next to the number one, which I think in my cake is pancakes Just like it is for you But what happens if you type in boobity boop? Or 42 Or donkey or whatever Well, you might think oh bash will give me an error message. No bash bash doesn't like complaining bash is bash doesn't do that Or you might think it'll just give you the prompt again No, it's like well you typed something. Okay, I'll take it What it does is it tries to map the value you typed to the list of options There is no such mapping. So it gives you the empty string So if you want to skip invalid items and just give the user the prompt back Or you could shout at them. I decided just to give the prompt back You need to check whether or not dollar item is empty Now you could do that with a double equals empty string But the minus z operator is by far the nicest way to check for nothingness because it works very universally So I did the same square bracket ampersand ampersand trick So open square bracket open square bracket minus z dollar item close square brackets close square bracket ampersand ampersand continue So break snaps you out of the loop completely Continue just says and back to the start of the loop So it just short circuits that loop through the loop Does that make sense? I'm a little bit confused. Uh, I I understand what your code does What I don't understand is why it doesn't seem to be breaking with mine So I I just purposely typed in boop at the prompt because that's what you said to type And it said I got the response back your order so far contains and it said nothing after it And then I put it done and then it said thank you your order is And then there's nothing Right because what you did was you appended to the array an empty string which bash went well, that's I that's really isn't anything So bash went and ignored your append Right, but it came back with the prompt it didn't it didn't barf on on this Well, yeah, right it won't barf it won't barf But it it executed all of your code with dollar item being nothing which in your case didn't do any harm But in the general case really could do harm right your code is not always going to be absolutely fine If something you think has a value is actually empty Okay In the case of my code it isn't nearly as elegant because it says added nothing to your order Because I'm printing out added dollar item to your order. So in my case it looks very silly if I don't skip Okay Okay, so it does my mind does look silly it says so far your order contains and then there's nothing there All right, so it had yeah, exactly so it continued through the loop with nothing That's in your code didn't really take that into account because I never told you to and I was kind of wondering If anyone would stumble on for a head of chance to tell you Yeah, well another way to do this would be to say If you know how many items are in your list to say if I don't get a 1 through 10 Then Say, sorry We don't have that But you never see you don't see what they type you see the mapping of what they type to the menu So the only thing you can actually check for is blankness Oh really But the user typed 10, but you got pancakes or whatever your 10th item is you didn't get 10 Right Yeah, so then I guess I don't really understand that you said you said there's a mapping from the number they put So the select creates those numbers Yeah, and it also creates the mapping to the number 10 in my case my case is done But let's say nine is more bacon because why shouldn't you have more bacon and so it's the select is mapping to more bacon Yeah So it doesn't know that I typed in a 10 No, you don't know what they typed in Your your code dollar item or whatever you named your variable is going to get The item in the menu. It's not getting interesting Well, it's not really limitation It's just an abstraction that chooses to use numbers at the end of the day What you want is the value they selected and they selected something that doesn't exist So the value you get is nothingness So the way you test if they typed something silly is Well, it gave me nothing. It wasn't on the menu. They obviously typed anything that's not on the menu will get you nothing Well, I guess you could check for nothing and say, I'm sorry. We don't have that Correct. Exactly. That's what you're supposed to do. So the check is much simpler than having to know how many items on the list It's just is it nothing If it's nothing, okay, so but I'm saying in your square bracket Double square brackets minus c dollar item. You could have the if statement go with that that says then print I'm sorry. We don't have that Yes, absolutely. Yeah, you could do you choose to react basically bash doesn't decide what to do you do And the way you figure out that you need to do something is by checking for nothingness That's one other thing In I don't remember you teaching us this but this would be the four thousandth time. You said, yes, I did if it's true Um, your echo statement at the end says echo minus e quote backslash n for a new line Um, I had to go find out that you had to put a minus e in order to use the new line Uh, I think I didn't didn't remember you teaching us that That may have be something I was meant to put in here as a potpourri thing and that may actually be something I Done so that I could tell you about it and then forgot to tell you about so I told you about it then I guess but it needs to go in the show notes now Oh I'll make a note for you. Yes, please. So yes without the minus e bash will just Assume that you didn't really want a new line and print you out backslash n and I don't Know where that I googled did I ever see anyone saying and for this really logical reason echo behaves like this What I see is lots of people going For reasons no one can remember because it was in the 70s and they were probably on drugs They decided to write it this way Okay, that's funny So minus e Minus e. Yeah, I don't even know what it sounds first. I don't be silly. I don't know One less tablet. I really don't know Is would it make sense to just always type echo minus e? Probably pretty much sure that you wanted to actually Properly print out your and instead of having to remember once in a you know Every 25th time that I've got to put a minus e and go Yeah Well, one of the tips you'll be getting in a future installment is that maybe instead of echo you can use the more powerful print f So that's probably the long-term solution is print f But it's it's a slightly more convoluted syntax, but it is more powerful So swings it around a bit, you know echo is easy print f is more powerful Different people like different things And then I did also make use of the even worse syntax dollar open curly bracket Octo thorp name of array open square bracket at symbol close square bracket close curly bracket to get the length of the array And the only saving grace is that the octo thorp is the counting symbol So it doesn't vaguely imply counting or Looking at something over noisy modem or like your cat run over your keyboard I got really good at this Because I started from the inside out every time. I said, okay, I want my array. My array is order Okay, I want to tell it to loop through all of the the things in the array. Okay, so I'm going to use I'll put square bracket out symbol after that. Okay next. I'm going to need to to tell it that I want um The uh, I want to say this is a variable, but I can't just put a dollar in front of this I got to put some squirrely brackets around it to hold that in place. Okay, good Now I want to count it. Let me stick in my octo thorp. So I did it methodically every time Instead of trying to memorize it or anything like that. I just said, let me build it each time and I got I got Fairly good at it after a while That is how I mentally do it every time as well and that works whether or not you're putting in the octo thorp You go through all the same steps except you don't get as far as and throw in the octo thorp So when I'm just accessing the array, I do the same mental That's why I came back to the octo thorp because I don't always need it But when I need it then I know it goes inside Yeah, exactly. So it works unless make sure it's inside quotes when you're done for the echo Yes, precisely, precisely Okay, so That gives us all of that. So then I thought well five more minutes. I'll just do the bonus I mean how hard can it be? We'll just read a file Appended to an array. We already know that your plus equals into the array We learned how to read a file a few installments back But that time we printed it to the screen because we didn't know about arrays yet So we just printed it to the screen And so you can read a file with the cat command And you can pipe the output of cat into a while loop So I thought wow, I'll just pipe the output of my menu Into a while loop And it'll be grand And I ran my code and it said please choose from done Nothing else there was nothing on the menu just done Okay, what? So my text file has a heck of a lot more than done because since I could put in comments And so there was a separate separate text file. I broke it apart and I had like You know pound sign sweet stuff pancakes waffles healthy stuff porridge music fried sausage bacon eggs and spam drinks Full menu here and then you know because I needed to test that it's calm the empty lines Yeah, exactly. I had to test to skip them and everything so I had all the all the all that stuff in there And I just said done What do you mean done? Do I not know how to append to an array? I was like, oh, yeah, I forgot the rounded brackets I actually don't know how to append to an array whoopsie better fix next week's show notes So I put the rounded brackets in felt very confident ran it again and got done Am I not reading the file? I'll put in an echo statement Perfect print out on my menu Printed out the very the array Nothing Where are my values going? I am adding them into the array and then the array is evaporating Actually, yes that is exactly what was happening Why it was happening is a subtlety that took me quite some time to figure out You said three hours. I think we are between before sleeping on it Looking at it going for a walk and then finally fixing it. I'd say so. Yeah I certainly wow. Yeah, it exercises the mind Anyway, there is something in bash that I know about That I wanted to tell you about later But I'm going to tell you about it now because it becomes important So in bash you have this concept of a sub shell Basically a bash within a bash And we've used it So when you take a command And you wrap it in round brackets and then stick a dollar on the front What you've actually done is you've said the bit in the round brackets is a separate little script Execute that separate little script and then the dollar sign says give me the value So you've been putting a bash script in a bash script Now what I haven't told you because it really doesn't matter is that in that little mini bash script in the bash script It gets a copy of your variables Note the word before you go too far I heard the word copy and I'll come back to that and that's clearly the important part of this story But what's an example of where I've done a sub shell within a shell? We would have assigned variables to the result of running a command We would have maybe piped something into a grep or something. I know we have used it in examples round brackets inside It's quote dollar item Is that a sub anytime there's parentheses? Are you saying that's when it's a sub shell? And when you stick commands inside of parentheses and when you're executing the command So if the thing that goes in is so if you have like a variable you want to say My hosts becomes equal to cat till the slash etc slash host or slash etc slash host How do you get the value from the command in you put it in parentheses with a dollar? Okay Oh, okay, so that's the command within the command. Okay. I'm caught up. Yeah, okay So you're saying we get a copy of So when you do that you're making a second bash and that second bash gets a copy of all of your variables So we can use any variables you've created But it gets a copy Of your variables, which is very safe. It means you don't get spooky action at a distance And it means you can still use the variables you set up But what if you want to change a variable? When your changes evaporate Now I did not intentionally make a sub shell But I did accidentally make a sub shell Because a very very very very important subtlety Is that when you pipe one command to another What bash does is it says the command on the left is a sub shell And the command on the right is a sub shell And I will take the output of one sub shell and make it the input to the next sub shell But they're both sub shells So when I said cat My menu file pipe while The entire while loop is in a sub shell Inside the while loop. I went menu plus equals item Okay, menu was a copy of my menu Soon as nothing in the menu. So as soon as the while loop finished and the sub shell exits The copy of my menu, which is full of stuff Evaporated because the sub shell came to an end And I was left with my original variable, which was completely untouched because it was copied into the sub shell And the original was entirely unaltered. So at the end of my loop. I had an empty menu Wait a minute, but the menu is an array that you define outside of your Correct outside of this pipe command. So why is it empty when you get when you get out? It should still be there No, because the entire while loop is in the sub shell Oh, hang on. Are you talking about the the the choice is the person made from the menu? No, so I am filling my menu, right? So if you look at my code Oh, you're filling your menu. You're filling your menu as an array for the in this while I'm sorry. This that's this so you the the menu is in a text file It's coming in you're populating the array with this while loop that's on the right side of the pipe So you're creating this menu and then it's empty when you come back out Yeah, so I entirely filled the menu and then throw it away I I took a copy of an empty array Filled it with my menu item and then threw it away and then was left going. Why is my array empty? Now if I had intentionally typed the round brackets, I would have known I was making a sub shell But it was an implicit sub shell because I chose to pipe I did eventually find the right magic words to make google tell me that But that was some serious google food before I finally got stack overflowed to tell me that one And then literally it was three words pipe makes sub shell and I just was like Oh, that's what is And then everything made sense the universe was the universe wasn't broken I just didn't understand what was going on in my own code and that's always what it ends up is the universe is fine But you're missing a piece of information a subtlety somewhere And that yeah, that was where three hours went. So then I went, okay great. I now know Why it's broken? Actually, I'd say that was only about like two and a half hours Then I was like, okay, this is why it's broken How do I unbreak it? How do I how do I get the content of my file into my loop? Without my loop vanishing off into a sub shell And the answer is very pleasing me something. I've been trying to find an excuse to tell you about So bash has the ability To define multi-line strings very nicely using the triple arrow syntax So we know that a single arrow You can redirect the output of a command to a file And a double arrow will append the output to a file And if you send a single arrow in the other direction, you're reading from the file into your command Well, if you use three arrows on the way in You take a string instead of the content of a file and the string becomes the input to the command I'm getting super lost and part of it's I'm used to following along in the show notes and I have no idea where we are So I'm I'm not being able to picture this in my head very well Is this are we at a spot in the show notes that I can identify? I'll use the following snipper to load the menu There it's the line above there is a lot in all caps Or sorry a lot in bold going on here I see I use the following snippet to load the menu. Okay, so where are you using? Okay, so Right, so I have while read minus or menu line then do lots and lots of code done So The done is the end of my while And at the end of the done is three arrows and then I'm feeding in some information So instead of cat pipe to my while loop I am triple arrowing into the back of my while loop So I did this with one arrow and just the file name Mine says done one arrow to the left Menu.txt Mine's a do loop with an with an I My reading is that that syntax isn't you isn't supported in all versions of bash I actually thought the Mac wouldn't let you do that lovely shortcut because you can also pull a file's content in that way Then you don't get to learn about multi-line strings And you're gonna have to back up and explain multi-line strings because I wasn't following you when you were going double triple Arrows I was getting lost because I was like I only used one Okay, so if you use one arrow the thing that comes after the arrow is the name of a file Correct and the value that gets shoved into your statement is the content of the file So there's a read there's a redirection going on here Your string is being turned into a file name the file is being loaded and then its content is going into your loop But sometimes you just want to specify a string And that string may go on in for a very long time And so the way you just say I I want to input this great big long string which may or may not contain new line characters Into my command is with the triple the triple arrow And it's called a here string For reasons I don't I can't figure out why it's called a here string. It's like here. Have a string Which are here? Here it's like here. Have a string I don't know And so you basically say triple arrow, and then you can either have a single or a double quote And then it will just keep taking the string until you close the quote and you could close the quote 500 lines later It doesn't care how many new line characters or what goes in between it'll just say Yeah, I'll keep taking it until you give me the closing string And then I'll take all of that string and shove it in as the input to the command But the string again in your case is the contents of the file the same as mine It is but I went and read the file by using a shell Yes Yes, so I very explicitly did what you did Okay So, uh, you you cat this menu dot txt But but you actually did some trickiness there To get the directory name to know where that menu dot txt file is can you explain that? That is next to my list. So remember I said there's a lot going on here. That is one of the many things going on here For the moment, let's ignore the fact that I'm doing that tricky stuff. So what am I doing inside my here string? I'm making a sub shell to cat my file into that string But because the sub shell is now entirely contained within the single string No problem All right, the sub shell has not infected my while loop because the sub shell is contained all within the string Which is why this works. So I still have a sub shell. It's just a sub shell hasn't Inveloped my whole while loop and hence it hasn't broken my universe So his sub shell Is written with this quote dollar parentheses and then he's got cat and he's going to talk to the file Yeah, so pretend that just says menu dot txt Yeah Right, but the parentheses is what gave you that that's what's creating the sub shell Correct, correct because you've got a command inside the parentheses. Okay. Yes. So you say cat And then what are you doing? Okay? So then what we want to do so I'm going to describe the problem to be solved before I tell you how I fix it so So far when we've been running our shell scripts, we've gone into the folder where the shell script is And we've said dot slash name of shell script So the current directory We're executing is the directory where the shell script is So by pure accident a relative path inside our script is relative to the script It's not really relative to the script. It's relative to the folder. We were in when we called the script So if you start writing shell scripts for real You're going to put them in a folder called tilde slash scripts or something And you're going to run them from goodness knows where Oh And so it won't know where it is So when you say dot slash menu dot txt, it's looking relative to where your terminal is Not relative to where the script is Right Which can be very different places So if I ran my script from uh my delete me folder and I said dot slash and I gave it the full path to my script It wouldn't be it wouldn't know where the menu file was Well, I would look for it in your delete me folder and go well, there's no menu here. It wouldn't be yeah, okay So it's a subtlety we haven't hit because we've always been in our folder But I thought this was an opportunity to remedy that oversight So there's a couple of pieces to how we do that So the first piece to how we do that is that bash gives you a special variable dollar bash underscore source in all caps That variable exists in every shell script And it's the full path to the shell script So if you're running if you're running so it won't exist in the terminal because the terminal isn't a shell script But if you run a shell script that variable Is created for you by bash and if you have a shell script that includes another shell script It's smart enough To follow it down that if the line of code is in the second shell script it'll be that shell scripts path So the variable always points to the actual place where the line of code running right now is Because you can have a shell script that calls a shell script that calls the shell script Oh, oh, so it's always correct. The bottom line is it's always correct The line of code that's the line right where you are The line right where you are is the file that it will know where you are And it will be your file for the very line of code you're using it on and if you use on a different line of code It'll be a different line of code. It's always right. That's a good thing. Okay, but it's the full path Including the name of the script We want the folder Okay Now we don't want the name of the script because I just want the menu file in the same folder as my script So I need to get rid of the file name. You could use regular expressions I promise you if you do that it will break because there will be a special character somewhere someday it will break Okay, so what we want to do is use the correct tool And the terminal provides us with two terminal commands designed for both halves of that job The commanded dir name takes any file path and gives you just the directory part And the command base name Throws away everything apart from the file name on the end So It basically splits it in pieces the folder. I've seen this in apple script. It looks it looks exactly like this in apple script It's a quite a common thing to want to do most languages have a way of Splitting a file path into the file bit and the folder bit. So here it's dir name base name So dir name or base name. I should probably not name many of my variables that Uh, well as long as you access no, you're fine because you'll be saying dollar dir name Okay, and this is dollar parentheses dir name. Correct. Which makes it which makes it a sub-shell where it's a command Correct. So you can actually type dir name straight into the terminal Yeah, yeah 10 out of 10, but you can use dir name in the terminal So you can say dir name space slash etc slash host and it'll tell you etc Or you can say base name slash etc slash host and it'll tell you hosts But that's only inside quotes and inside parentheses and with a dollar symbol around it No, no, no, no, no. So inside quotes with a dollar symbol is to pull the value of the command into the string But if you're just on the terminal you can just type dir name Till dir name any file path you want and it'll split it up for you Right. It is a terminal command like cat or like whatever So why in the show notes did you do it with the dollar parentheses around it? Because I don't want to print it through the screen. I want to actually pull it into my string Which I'm going to then pipe into my while loop No, I'm sorry. I mean in the example that you give in the show notes where you You're at the at the command line doing it. You could have done it without the You didn't need the quotes and the dollar and the and the parentheses around dir name I guess because I was trying to make it look more like my code. Um, it sounds like not a bad idea Right. Yeah, okay. They are just terminal commands We would generally use them by saying pull this into a string So we would generally use them inside our quotes and stuff, but it is just a terminal command like cat or echo or anything else Very interesting very interesting I did wonder about that when I was doing this like, oh, I hope it knows where menu dot txt is I just I just I didn't even well you talked about dot slash, but I just said Menu dot txt because it was in the same directory with me And that is Not starting it with a slash is effectively the same as the dot slash If it starts with a slash it's an absolute path everything else as well as Okay So that is yeah, so dot slash menu and menu are the same All right So I used my my single arrow menu dot txt at the end of my do loop going through my breakfast menu with a With a value I was looping through But I could change that now to this triple arrow Uh You don't even if the single arrow works in mac os 10 you can actually just use that I didn't think it would My reading was that it was added to a more recent version of bash. I'm glad to be wrong about that I'm glad that does actually work on the mac Oh, okay So I'm not wrong to use it. You're not wrong to use it The only thing you need to do is instead of saying the name of the file after your arrow You want to have a string after your arrow so double quotes So your arrow and then immediately double quote and then inside the string you want to use a soap shell to get that Dear name that der name right right So it's dollar sign open round your bracket der name and then whenever you're The so I don't need to do yeah, I still need the best source, right? Yeah, because that's what you want to get the der name of Yeah And then your slash menu dot txt or whatever you called your file you probably did call it menu dot txt, isn't you? I did, you know, there's not a lot of options. I thought about breakfast menu and then I was typing a lot of words Yeah, exactly menu dot txt is easier when it comes in. I called it breakfast menu though because I because I thought bm would sound bad This is worse b. Oh, it would have been worse. Um But yeah, so that's that's basically it so they're they're the various little tips and tricks so that I really wanted to tell the story about How the tiniest of little thing can throw you for a loop and honestly it felt like the universe didn't make sense I was like, but I'm appending it to my array I can do an echo statement. It's here Where is it going? How is it evaporating? Where's it vanishing to it was very frustrating? And the point is it happens to everyone everyone will experience this and when it happens to you Don't feel bad. Don't feel it's something wrong with you. No, it it just happens everyone 20 years in still happens 50 years. I think that's a great lesson. I I'm sure I've talked about on the nocella cast I don't remember if I've talked about it here, but uh when I was working. Uh, we worked with giant mirrors And uh, my boss dropped a screwdriver on a 60 000 dollar polished beryllium mirror And it was the best day of my life Because he was like the golden child could do no wrong and I was like, I'm never doing anything that stupid Luckily, I didn't but it would just made it. It was a it was a release. It was relief I knew that that I was like, okay Bad, you know, people do stupid things, you know, yeah I make a point on any Whenever we hire a new system and I make a point on the first day to say look you will make mistakes Don't cover them up. Tell us about them and we'll fix them I deleted every single computer from the active directory domain With a misplaced star Trust me. You'll make a mistake Just tell us about it. We'll fix it And they like the fact that oh right, you know, it's okay to be human here And uh, it is always easier to fix the problem you know about instead of having to try to figure out what was broken and then try to fix it So anyway, it's look it's always good everyone everyone everyone makes mistakes and always remember that when you're being frustrated and cranky It happens everyone So next time was a good lesson It was a good lesson and next time we will pick up where I hadn't I'd expected to be this time so we will continue to turn our shell scripts into I would say first class terminal citizens We'll make our shell scripts behave like the terminal commands you know and love or no one hate like the terminal commands you know It will behave like the others whether you agree or disagree. It will be terminal-ish and it's always My view is always Make your stuff fit into the language you're working in so People look at me and they go But when you're writing java, you use camel case when you're writing power shell You use pascal case and when you're writing in pearl you use underscores. Doesn't that drive you nuts? It's like no In pearl land Every api is in this case So my code fits in perfectly In java land everything is in camel case unless it's the name of a class in which case it's in pascal case But there's rules and I just follow the rules And whatever language you're in follow the rules and your life will be so much easier And you will be trying to remember just the function I wrote and therefore I did it in my way Or is this a standard function therefore it's capitalized completely different just go with the flow And so I would advise you believe if you don't like the way the terminal commands do things Write your shell scripts to behave like terminal commands It'll just be easier Yeah, that that definitely does sound good Okay, so we're going to pick up. Uh, what are the what's the subject of next week though? So next week we're going to learn about something called get ops, which allows us to have minus a You know an artichoke. I don't know whatever We basically add those little flags To your shell script and have it process the flag so that you having to write lots and lots of code Because get off does almost all the work for you, which is quite nice Uh, and then we'll also learn how to make your script. So when you pipe And you make a sub shell, but when you pipe stuff to your shell script Your shell script has a small amount of work to do to accept the content of the pipe The terminal will arrange it so that the content piped to your shell script will be available to your shell script But your shell script does have to take it It's like the terminal you can lead a horse to water Or you can pipe content to a shell script But the shell script does actually have to take it and so we haven't learned how to take How to know there is input And then when you know it's there, how do I read it? And then you can do clever things like saying if you like the grep command is a lovely example You normally if you use grep without a pipe You specify Where you want it to grep and then what you sorry you specify what you want to grep and then where you want to grep it So you're saying the input the place to go look is the second argument But when you say cat my file pipe grep You only give grep one argument So grep is clearly doing some intelligence there. It is saying if there is pipe input No need for a second argument If there is no pipe input, I shall treat the second argument as a file name and go fetch the content myself So there's an if statement inside grep somewhere Okay, right That is what we're going to learn to do to be able to to create that same Intelligence in our scripts So we're we're definitely taking up a notch in complexity here Believe it or not, it'll be like one or two lines of code But unless you know them unless you know them you can't use them So that's the it's like I say we're making our shell scripts behave like terminal commands And I know you like a challenge and since we have this shiny new community. We should do something with it. So in Kind of in preparation to be honest because it'll be convenient to have this as a starting point for next time's examples So I would like you to take your current solution to the current challenge And allow it to accept an optional argument So in this case, it doesn't take any arguments yet. So your optional argument shall be your first argument And that argument if present should be a number which is the limit on the amount of things you are allowed to order And then so you're saying you would say run the script space seven and then It would only take the first seven of the 10 maybe that you had in your input file No, no not limit the menu limit the customer So your select loop should go around up to a maximum of Seven times So you can still hit don't at any point But if you try to go beyond seven or whatever number you pass as the first argument you to say, I'm sorry But there is a maximum item per customer of whatever Your tray is so big. I don't know Can I add a challenge? I thought would be fun to add to it that might not teach him anything I was going to say what if somebody asked for blueberry pancakes and that's not on the menu What if it could your thing could say oh, that's a great idea. Let's add that to the menu And update the the text file Well, but given our conversation about the fact that you're never presented with the input You're only being told the mapping into your menu You have no way of doing that We explain that again So remember we said that you typed it over 10 or whatever disappears when you write it Oh, because you're not you're not writing Oh, I got it. Well, that's no fun. Never mind. It's fine. We'll just limit the people they can't have as much as can add food There is a there is a way to achieve your functionality So you know that if they type something you don't have it will give you it will give you an empty string And then you can use an if statement to take an action on that empty string You could take as an action Echo Oh, it seems that we don't offer something you would like Is there anything you'd like me to add to the menu question mark and then use a read minus p To get the value from them And you could then Append that so all you know is they asked you for something you don't have but you don't know what that something is So you can ask them So hey, did you did you type with that or is there actually something we should add to our menu? Yeah Okay That can be done and you could append it to the file Yeah, that's what I thought would be fun. I don't know how to do it Well, you're quite close actually with your arrow Yeah, I may have told you halfway through how to append maybe two arrows Um, so yeah, that that is certainly that is certainly doable that that is That is a more challenging challenge than what I had in mind, but perfectly doable perfectly doable. It is possible I'm looking for any excuse to keep playing with this because I'm having so much fun with it. Good Good, that makes me very very happy. That is perfect Right. Well, that is uh, that is that is all I got to me show notes. So, uh Until next time continued happy computing If you learn as much from barn each week as I do I'd like you to go over to let's dash talk dot ie And press one of the buttons over there to help support him He does 98 of the work here I'm just the stooge that listens to him and asks the dumb questions If you go over to let's dash talk dot ie you can support him on patreon You can donate via paypal or you can use one of his referral links I really hope you'll go over and help him out In the meantime, you can contact me at pod feet or check out all of the shows we do over there over at pod feet dot com Thanks for listening and stay subscribed