I'm here. The last minute jitters. Well, nobody says I use Ubuntu, by the way, but I might as well start saying that because that's kind of my thing. That's true. Yeah. Wait, what? This whole time. Damn. That's weird. Yeah, okay. They were probably definitely WTF-ing. Okay. All right. Hey, everybody. We're live. We're not prepared for this at all. TFL is here. He's way more prepared than I am, which shouldn't surprise anybody. We're winging this as much as one can wing literally anything. The way we've had to do this, if you notice, is that we're having to share the Discord window through OBS, and then I'm going to have to manually switch between the screens that we're sharing. In the chat, of course, on a different workspace, I have the chat. If you say something in the chat, there's a good chance I'm going to miss it. I am watching chat on my phone, though, so I might be able to see it. The good thing about having two people is at least one of us should be able to pay some people to do something, although there's no guarantee of that either. True. The point of today's stream is that's a good question, because we're going to talk about scripting. We're going to do a little bit of scripting. TFL is going to school me on how to script things. That's the most general description of what we're going to do, because I have no clue what. I'm not prepared for this at all.  We do this again. I promise I'll be more prepared. It's okay. It is fun nonetheless. I'm sure you'll enjoy it. We're just going to BS for the next hour, hour and a half. We're going to talk a little bit of scripting. Let's start off with this. Terminal for life. What is your favorite part of scripting?  I'm very curious. Interesting. The power. It's nice to feel like I can basically do anything with my, well, more or less, anything with my system with just a few lines of shell code. That's pretty nice. I guess. What else? I can do programming without breaking my brain.  I can just jump into shell programming and do a whole bunch of really cool stuff without typing out lines and lines and lines of code and something else that is not so abstracted. Yeah. That's cool. I'm not a shell scripter at all. I don't do bash scripting. I don't consider myself someone who does it because most of my stuff comes from other people. I have very few that I've done myself like that are actually, I mean, I have some auto start files that I've done myself. I've done DWM scripter, which is the only one I did. I did that key helper one that had all the sub shells or whatever they're called. I think that gives you an idea of my level of numeness. I'd like to tell the story. I have a temperature script that shows the CPU temperature. It was the jankiest-script that's ever been written. It uses LM sensors to grab the script and then use grep or something like that in order to pull just the temperature that I needed out of it. Then that saved it to a file. Then I ran that script every three minutes from with a cron job. It saved that to a file every three minutes. Then what I had my bar do, my DWM bar, do is grab the last line in that file every time using tail. Oh my God. I got it. Yeah. So I thought it was perfectly fine. But then when I went through and when I went through and did a distro hop, I realized that that file that that cron job had been saving to for the last three months was 15 gigabytes because it just had line after line of fetching the temperature for the CPU every three minutes. It never deleted anything. So that's my level of numeness. Also, I realized TFL is that when I switched to my screen on the Discord here and then I moved to a different workspace, it disables my desktop sharing. So nobody can actually see my desktop using that. So this is completely bored. Discord is trash. So what we're going to have him to do is so when I need to share my screen, we'll actually have to share it through Discord. And then when I want to share your screen off to share the Discord scene, this is okay. I think what we should do is say screw scripting and somebody needs to come on and tell us how to use Discord and OBS because it's obvious that we have no clue what the hell we're doing. All right. The only other way I can think of is if you just simply share your screen, don't worry about my screen or anything like that. Just simply focus, record just your screen. And I can just try to advise you. It'll be a little bit awkward, but I can still try to advise you. Well, we won't need to see your screen until you share something and it'll be easy enough to just switch to that when I need to. But for until that point, I'll just keep mine here on the screen. That makes sense. Yeah, that works. Yeah, that works. We did get together like, I don't know, like 40 minutes early or something, like half an hour early and we tried to organize ourselves. That was basically a waste of time because we didn't organize ourselves. Yeah, it was a fail. All right. Anyways, so I think what I'm going to do is we're going to open up what I should do, what we should have done is make sure you actually had these scripts so that you could. Oh, yeah. So somebody says, can I get a link for the Linux cast, please? Bro, you're on the channel. I don't know what you mean. If you're talking about the GitHub stuff for my GitHub stuff, it's in the video description. And you can find the link to TFL stuff in the video description as well. You just have to go to his channel to find it. Yo, I don't have a plus no one can actually share links in the chat. So ask you for a link. It's not going to actually help. Oh, you mean the Discord channel? Yeah, the Linux Cast Discord channel is not public, so you can't join it. Sorry. Yeah. Maybe someday it will go public, but I'm wary of it. So what is your repository called that has the files that you want to show me? Is that the one that's just script? It's just scripts, yeah. Okay, I'm cloning that now. Okay, that's quick. Yeah, that's not. Half of these scripts are literally just echo icon. It's literally... Okay. So if you see CPU icon to SH, you go into that. It's literally just the shebang and it's the echo icon because I use this for the bars. And I like to be able to change those icons when I do racing without actually having to go through and edit the SL status thing because you have to rebuild the SL status thing from scratch. You have to recompile them. It's not necessarily a big deal, but I don't want to do that every single time I change an icon. So I just put the script in the SL status thing, build that then, and then I can go through and change these scripts to different icons if I want to. That's a good idea. I could probably do the same thing actually. Unfortunately, you can't do the colors from the scripts. You have to do the colors from the SL status because that'd be cool because then I could just change the colors in the scripts. But again, you can't do that because although SL status just uses X set root. So you could use something like those Bash, what are those called? Exit codes? I remember. Escape sequences. Exit, escape. I mean, I'm very close to the word. So I could use something like that to change those colors. I don't know how that would work with SL status, but would you work with X set root for sure? And then I could use mouse events. Maybe that's something I could do someday. My chat has just suddenly updated that there was nothing for ages and now suddenly there's like a whole practice. So yeah, I missed a whole lot. Oh, I got a change from top chat. Oh yeah, live chat. Yeah. And I can't actually do that. Of course I can't do that. However, if you want, by the way, and I see you're there. He seems to get a kick out of me saying smoy, oh, okay. There's reasons. Okay, back to Tyler. All right. Yeah. Been doing this for now for 13 minutes.  Okay, so I'm going to go into, um, let's focus on, let's see here. All right. I want to learn about hear docs. Can you explain hear docs for me? TFL? Sure. Mind if, uh, if I show you instead, I think it might be easier to show you. Give me a second. I will change so that people can see you. Yep. There we go. Okay. So, um, I wish I could load up for auto exact here, but I can't. So it is going to be a little bit janky. Um, so if I do use a bit environment bash, my usual kind of thing, and I use the, usually I like, well, I can call it an incorporate a worry loop, but that's going to be a bit of a cool to begin with. So, uh, you can just use cat. So cat is going to, from standard input, read the contents of everything, all this stuff. And the, the way to, for, to tell cat in this case, where the end of the file is, this being the file, uh, you, you have to put whatever you put here at the end, um, on its own. And this kind of, this, what I've highlighted right here is the hear doc. So it's basically just a really, it's just a more elaborate way of sending stuff to something by standard input. So you could use this to say in a script, send a, a, a, a line by line, something or the other. So I, I think I've used this. And by use, I mean, I copied from somebody else. Um, in my DWM riser script, I went through and use a hear doc to, um, put in the, uh, DWM desktop file. So, and that has several lines of, uh, things that you need in order to send, to start the DWM from the, like the display manager, right. And, uh, I use hear doc in order to put that into the DWM desktop file, because it doesn't exist. You had to create it in the script. Um, so you could use that to cat into like another file that you're creating inside of a script, right? If that made any sense at all, probably cut into a file. Um, no, you don't really, you don't, there's no cutting into a file. I've got another idea that might make it a bit clearer. So that is that one. Uh, and because I'm using a dash there, I can get away with just putting tabs in because they're not, that's just a bash isn't much as that I get out of the way. Um, so this is ignoring the tabs quite literally the equivalent of, uh, using something like printf and saying example one new line example two, and then piping that into cat, assuming cat reads from standard input, I think it does. So that should, if I were to enter that in the command line, I'm assuming that would show example one new line example two. So it's like doing that. Hopefully that makes it a little bit clearer. Okay. So if the, in my, uh, DWM, or my DWM rice here when I used cat to actually input into another file, I could probably use like echo into a here. Could you use like echo or printf into a here doc? Something because what I did, what I did was I use that to, basically print out into the desktop file. Well, you can use a here doc to put something into something. So you can cat and then incorporate this here doc and then, uh, essentially redirect that into something or pipe that into something. So you can pipe the contents of this into say D menu, for example, and then D menu would show example one example two as options. Okay. Hopefully I didn't jump ahead too much there. Well, no, I'm just, I think the way I ended up using it there in that, because I mean, you have, you probably can actually see how I did it. It's in the, um, what's it called? It's a good question. I don't think it's, it may not actually be in there. Um, I don't, it's in the, it's in a different repository because of course it is. Oh, okay. Yeah. It's in the, uh, it actually has its own, its own repository, um, DWM riser. Okay. Yeah. And it's the dot sh one. Yeah. Cool. It's at the, all the way at the end. Okay. Of course it is. Uh, oh, and I see into file. Yeah. Um, I'm just trying to find the start of it because at least, okay. Yes, I got it. Yeah. Um, yeah. It has to use sudo because it's in Etsy. I've never seen a here dot like that before. That's breaking my brain a bit. I'm sure it is. I'm told. Is that even valid center? I didn't even know that was valid. It works. That's bizarre. Um, I, I'm going to guess it's just like, yeah. Okay. Well, that I've just, I've learned something new. Yeah. That was unexpected. So I would have ordinarily done something like that, but apparently you can do that the other way around and it doesn't matter which audio type I didn't assuming this does still work, which I assume it does. Yeah. Yeah. I just learned something cool. I am still going to put that on the end just to make it clearer, but uh, I guess it doesn't really matter anyway. Um, yes, that is exactly what I was on about. Yeah. So it's using cat there appropriate or should you use something different? Um, it's inefficient. It's definitely not efficient because you're bringing in an entire program there when, as I usually say, uh, some people might not agree with me here, but, um, the bash is more than capable of doing it itself. I'm assuming you use, yeah, use a bash. Um, so you could do something like while, while read, do done and then bring in the hit doc and do your stuff and send that stuff to the file if you want. And here would be printf. This is why handle is actually echoing that data, but that data, thanks to while read loop is being sent to the file and the reason I put this at the end or one of the reasons or one reason why I would say insist that you still do that is because it makes it easy to understand what's going on. Um, so in this case, it bear with me. So in this case, uh, this is printing each one of these lines that you feed into it, uh, as though you literally went printf, blah, blah, blah, SD, FA, SD, and so on and so on. Uh, and then the next time and so on. Um, I've realized that your, your while read loops is probably something you struggle with as well. But, uh, oh, well, we're here now. Um, I struggle with everything. So everything that you. So really, the, the fact is the while read, the while read loop. Well, you probably should learn. I mean, first let's learn how to spell bash and then we can move there. That's basically where I am. That's how you spell it. I'm, I'm completely an utter noob. The fact that this scripting exists in the first place is just a shocker because I did write it like myself, right? I did get other ideas from like the, the hear doc had new, when I wrote this had no clue what a hear doc was. Uh, and actually I had forgotten what a hear doc was again after this because I never used it since.  So like I said, does this make more sense now though? It does a little bit. I don't under, I think I'm thinking of it wrong because it's just, I don't know how to explain it. Well, if you take out this part, then all of this is going to do is literally print this out onto the, into the terminal or onto the tone. Um, I can't think of a way to demonstrate that. It's just a line separated value of whatever you enter into the hear doc, right? Yeah, pretty much. So I just entered all of that really, really quickly because I'm an expert typist like that and all of this stuff came out. Uh, but what you did because you used a redirection operator and sent that to a file, uh, you, what you did, you did that. So instead of this, you know, being sent to standard output and the terminal, uh, instead it was sent to that file. So now I can open, uh, file and there it is. Okay. Yeah. I think I'm there. Um, what, okay. So what other uses would hear doc have? I'm curious. Um, obviously other than the rudimentary thing that I use. One of my favorite, one of my favorite uses, um, one program is, uh, for, um, this for usage output.  Cause we're just massive pity us. All you have to do is stick in it, what, um, ignore the library loop, pretend this is just cat. Uh, but what you need is the hit doc and it makes life so much easier. Uh, so that's, that's one of the main ways I use, um, a hear doc is for usage output. Okay. So the question while you're there on that, what's the difference between doing that and using the, cause there's another one that you can use to do the display that like the help menu or whatever it's called like ops or something. Get ops. Am I, am I, am I making this? That's for argument passing, not really displaying data. Get ops is a way to pass arguments, which I never use. So I know bugger all about it. I've always preferred to just do it. The more manual approach using a wide read loop and stuff. So basically that probably just does a while we do, there's kind of like similar things that you have this, they have like, cause when I was going through and creating the, when I was doing the best challenge thing I was thinking about adding that menu or whatever that you would get if you just entered the, uh, the program name or whatever and just pops up the, the usage thing. And when I was doing the research for that, I came across that ops thing or whatever. And I was starting to figure out what, cause I noticed that you did it this way. I was trying to figure out what the difference was. So get ops can actually display usage information. Cause I actually didn't know that. That's, if it does, that's pretty cool. I could possibly be just, I mean, making it up in my mind. I could have been very delusional when I did it, but I feel like I remember reading that that get ops is what you use to display help menu. I remember that being something that you struggle with as well. You mentioned this in the past that you struggle with argument passing a lot. Actually, I think like, yeah, everything meant I'm telling you, there's not much here that I don't just struggle with. That's why I'm learning the echo command. All right.  What's the difference between echo and printf other than printf? Oh, I knew that was going to come up. Printf obviously has more ability to read, like more stuff. And you can use like, what do you call those things, like reject things, right? So much specifications. Yeah, that. I'm so sad that I know this stuff. No, it's fantastic that you're able to translate my mumbling into actual what it's supposed to be, because I don't know the terms. That's my problem is I don't know the terms. Like what I need to do is actually sit down and take a course. I have one saved that I'm actually go through one of these days, but I just, you don't need to take a course. Just watch my videos. Every time I watch your videos, I feel like I'm way far behind because it feels like you're really not. It's just my channel focuses on the more advanced stuff. Yeah.  And then I get, I like, wow, that's, that's really advanced.  And I like, wow, that's really cool. Well, yeah, print F basically, I mean, it's print F. The F actually means format as far as I know, or at least that's that makes sense. You basically print something in a formatted way. That's the whole thing with print F in any language, as far as I know, any language I've used at least.  Just like tables, you can have dynamically sized tables by using print F a few other things, but print F is the crux of it. And that's really cool. Because then you get things like this, even though I probably wrote this in power, but let's just pretend I wrote this in Pash. And that's, that's pretty cool. You get a nice, you know, see how everything's dynamically sized, sized according to like the length of the, the widest thingy here, which would be this. So this table, sorry, this column stays that, that width. So print F is really the heart of letting you do things like that, because it formatted the text. And echo just prints something out without any of that capability. Yeah, it's bog standard, but you have to remember that they're both built-ins.  Don't use echo.  The fact is they're both built-ins. They're both built into the shell. I know there is a good alternative, but they are both built into the shell. So you're not really breaking some forbidden, unwritten rule, you know, by using echo. The only thing with echo that might be worth keeping in mind is that my echo is not probably like your echo. Your echo, you probably use that to expand escape sequences like that, for example. Whereas my echo does that by default. So it would depend how echo works depends on how you have it configured. Okay. I don't have it configured. I just use whatever. Yeah. So by default, you will have to use that E-flag, I think. But there's a special... Oh, you use that as a Sage anyway, don't you? I do use the Sage, yep. For the pretty color. If you're using Bash, and then... Yeah, don't blame me. If you're using Bash and then you sourced a file, then if you had echo configured in a different way, then I had it configured and I programmed only for mine, then you would get screwed over. Okay. So that's interesting. So is that a good reason to use printf instead, because printf would correlate better between systems? Frankly, you're probably going to be fine using echo unless what you're writing is intended to be sourced, such as some kind of plugin or something for Bash. Otherwise, you can just get away with echo as far as I know, unless they've somehow hard-coded, like compiled Bash without echo support or something weird like that. Okay. You mentioned escape sequences. Escape sequences are the things that you use to X to create colors in Bash, right? But there are other escape sequences, right? So explain those a little more. I remember the colors. I got those down. What are the other ones? You don't have to go through all of them. I'm sure there's a lot. I don't even know. There are a lot. Yeah, there are a lot. So that's new line. You know the new line character is right. Yeah. Yeah. Okay. And the R one's an interesting one. So if let's say you're doing like echo, well, let's go for printf because again, who knows how your echo is configured. So printf and let's say something and the new line character. Well, let's not have that new line character. So if I were to execute that, let's pretend this is actual commands. Why am I doing it like that when I cannot actually just execute it? Okay. So printf, something. Yes, that doesn't quite work how I thought because of my prompt. Bear with me. Wrong flag. There we go. Probably still won't work how I'm thinking it something. Yeah, not quite how I was thinking it. All right. That was a fail. Let's try this. Let's try this again. So printf, load of stuff and what do you see?  I'm just going around to circles here. How can I word this in a way that actually makes sense? Let's say you're within a script and you use printf. There is no prompt. So that's the thing that's tripping me up right now. So there's no prompt to your end script and you're using printf and you're printing something gobbledygook. And then you have printf again. But let's say you want to get rid of this on the same line because printf is picking up since there's no new line character here. It's picking up right here. But if you use the R escape sequence or escape character, what it will do is it will actually delete all of that until they start the line and then start printing wherever you put it after it. This can be really, really, really useful if you have some kind of counter that you can just like scrap the existing value. Say if you're counting up to 100% or something, you can scrap the existing value and then reprint the new value. And that's how a lot of times people are getting these really nice counters to display properly. So that's just one escape sequence. I thought I'd put some time into because it's a really cool one. That is cool. Yeah. Of course, yeah, you've got the numbers. So these ones are actually anti color escape sequences. Because I assume they're from like the I don't know the part of ANSI or something, which is like some kind of American standard thing. I can't recall it. But so you're familiar with them. I guess I do want to push. Did I run through some of them? Do you think if you want to? Sure. If not, we can because you did a whole either you did you do it on a video or did you do it? Oh, yeah, I did. I think I did a video on and that might have been a stream, but I did something on it. Yeah. Yeah, that's where I learned it was from you. So oh, okay. I learned I learned the escape sequences. Of course, I always call them exit sequences. So I mean, yeah, yeah. Okay, I guess I'll just go over some really quick ones then. You've got 30. 30 to 37. Those are your regular colors. So 37 is white 30, I believe is black. So 31 is red. 32 is green, I think 33, I think is yellow might have that the other way around. Four is blue and a whole bunch of others. I think five might be sion. I almost remember them all. That's that's pretty sad. So there is there are those colors 30 to 37. But then you have 90 to 97. A lot of people they will they like me back in the day back into the day, I would cheat and I forgot about the end by the way, I would cheat and I would actually put in something like one to which actually means bright from correctly. So 97 is very or can be depending on how your terminals configured can be very similar to bright. And you might see that I might separate these out with the semicolon. This is this right here. It's just one digit. You've got some like attributes that come like changing a font to bold or italic or something like that. They're not changing the color but they're changing the actual attribute. So you have one, for example, being bright to is dim. And then you've got a whole load of others that there are loads of really interesting ones like italic flashing and all that kind of stuff. So you can actually mix and match these stuff and these things. And you can also set background colors and do all that stuff which I actually cannot remember how to do because I never do it. But that is possible. So the general gist is you've got the attribute which you can set and then you've got the actual color itself, the foreground color, I should say. And you can mix and match these. So if you want a brighter and not necessarily bright or bold or however you want to call it, but you want a brighter or lighter red, you would choose or can choose 9.1 which would be a lighter red. Or you can choose a darker red or the so-called normal red and you can choose that. Or you can say actually have a bright red and add the bright thing or attribute and then say 31 or if you want to have a really, really, really bright red go for that. And so on and so on it goes. So hopefully that was at all interesting. That was cool. I'm going to eventually try that out in the exit route for the D-Dayman bar script because then I could set the colors from there instead of having to use the stupid patch that they have in order to change colors. The only thing I totally forgot to do was actually demonstrate that. And by the way with the E you can actually make that 033. Which is actually really useful in something like orc because the backstash E doesn't seem to work in orc for some reason, but you can use backstash 033 and then it does work which is kind of cool. So there's the red. I'm going to put a new line character. We get the red and then the bright red or dim red or a lighter red and so on. Man that is really cool. Excuse me. All right. I think we've been ignoring people for a while. Oh yeah. Sorry about people. All right. So take some pressure off from me chat. Are there any questions you'd like to ask TFL? We'll ask them in the chat. And here's our bash expert. Is there anything that you want to know about bash to lead us along just a little bit? And while we're waiting for questions, let's ask a complicated question. Explain to me while loops. I don't know anything about them. Assume you know nothing. You want me to explain the while loops? Sorry. I was reading chat. I thought you were talking to chat. Okay. You want me to explain while loops? Well, we could try to have chat explain while loops. Some of them their explanations should be fairly interesting. I'm assuming some of them probably know what they're talking about and some of them are probably like me and they probably know how to spell while but probably not. That's as far as I go. So explain. I have no clue. To me or chat. Definitely you. Okay. Right. It's funny actually because I just recently attempted to make a video that it basically went through until loops while loops for loops both C star and regular and if statements and case statements and I just hated the result.  I hated it. So yeah, here I am. And now it looks like I'm doing a little bit that anyway. You're good. That's you. The best videos are when you wing it. It's going to be okay. That's what I thought. So it's the synopsis of a while loop is really put straight forward. Let's just make sure people realize that this is talking about bash it. Not really. But let's just for the sake of argument say that this is about bash. So while condition do done commands. So provided that this condition is true, commands will be executed over and over and over and over and over and over and over and over again as fast as it possibly can, which can be a problem, which is why you sometimes see people see people using sleep depending on what they're doing. But anyway, the gist is as long as this condition is true, execute the commands over and over. Okay. That's what's very simple. Yeah, I actually understood that. That's good. Awesome. Because I had no clue what that meant. So what what possible I mean, obviously, I think conditions would be basically like an infinite number of possibilities, right? But what are some examples of conditions that you could use? Okay, well, a common one that isn't really fitting for a while route, but I'll show it anyway. You might have saved a number. You probably some some of you will know exactly where I'm going with this, but you might have number is equal to one. And let's say I'm going to use arithmetic expansion here. Sorry, arithmetic evaluation. The expansion would be that. And I'm going to say this, this is a test by the way, but it's strictly for arithmetic, just in case you're not familiar with it. I could do this with regular a regular test using, you know, square brackets as people call it. Anyway, so number if a while number is less than or equal to 10. Let's echo number. And because we're using bash, we can bring in the let built in and say let number plus plus is the incremental thing. So we're saying number plus number plus one basically. So this will reassign the value of number to number plus one. So what you will see from that is one, two, three, four, five, six, seven, eight, and nine, because I'm sorry, and 10, you know, because well, let's let's walk through it the first time round number is equal to one. And then it reads this bash reads this line, it's goes, Oh, well is number, which is currently one, is that less than or equal to 10? Yes. So this returns true. This this test returns true. So this condition is true. Therefore, this these execute so echo then echoes one, and then this let built in is is incrementing that. So then it becomes two and so on and so on and so on until it's finished running through 10. But then we have number is equal to 10. Is that less than or equal to 10? No, sorry, this would be 11. Sorry, is 11 less than or equal to 10? Obviously not. Therefore, these then execute these this condition is no longer true. And we exit out of the while loop. Okay. I felt like I need to drop a mic now. You definitely should because that was very impressive. Okay, so that makes a lot that makes a lot of a lot of sense. And it would definitely is more something that I could, I definitely got my head around it easier than if I had read it. So we can consider that a win. Okay. So that's while loops. Let's see. There's also until loops. All right, what are really easy until loops are basically while loops in reverse, that's really all it comes down to. So I rarely use until loops, but there comes a time if you now and again, when it's just easier to type until and rather than using, you know, a bang or an exclamation mark to negate a test and negate a condition. Okay. So Schmog or whatever his name is, he said auto exec would be very useful here. Yes, it would. We had some discord problems. We can't get two different terminals to be on screen at the same time. Yeah. Discord is dumb. So we understand that. Somebody asked, other than we have a whole bunch of people explaining while loops, which I find highly entertaining. Somebody, I've lost it already. Somebody asked something quite interesting. Good TFL with a script for changing wallpapers every five minutes. Might be a good demo of some batch scripting. Have that if that's what you want. If you'd like to do that, let's go ahead. Well, the thing is, here's one I made earlier. Oh, I can't remember where it is, but I have done something like, yeah, I think it might, is it an extra or as part of You care on reading chat and might take me a moment to find this thing.  TFS. What the hell's TFS? I do the same thing with some of them, for sure. Face slides. That's it. I don't think face slides actually changes to a random wallpaper. Okay, it's not too long. Yeah, it's not too bad. But it does change to, it's basically, as the name implies, slides. It's a slideshow of wallpapers, and it will set those wallpapers. I actually used this for a long time, but back in my really old videos, I doubt anyone remembers, but it was one of your steampunk videos at wallpapers a lot. I think if I saw one of your videos with a different wallpaper, I'd probably assume that it was somebody else or maybe somebody hacked your channel. Yeah, because I always have the one with the damn logo. So, Zanyi, would you be interested in me walking through this script, and anyone else would you want me to walk through it? I'm interested. Well, you're interested. Screw the rest. Screw everyone else. I'm the only one that actually talking about. So, do you want me to walk through the whole thing line by line? Do those stuff that's most interesting to you, the stuff that you think would... I mean, you've already talked about the while loops and stuff, I guess. So, we can kind of summarize those. I don't have to be line by line of the while loops. I'll skip all of that and that and that and that. And I guess it really just comes down to this. So, it's been a while since I've actually looked at this code, but hopefully I can get in the right mindset. So, we've got a test for whether something is a directory here. This would presumably be the directory in which to use to set wallpapers. So, I have to check that that's a valid directory. This is... I love to test in scripts. So, it's always important to try to catch errors and handle them accordingly and make sure the code isn't unnecessarily running, breaking things. I always try to make things robust is what I'm trying to say. Okay. So, we've got a while loop here. And the use of this colon here is actually synonymous with true. So, it's sort of a pro tip for you, I guess. It's a shorthand for true. All the leap shell programmers use that. I'm just kidding, but it is pretty handy. It saves a few keystrokes. So, it's kind of cool. Anyway, and this is... Some people ask me, this is valid in BornShell of immigrantly, but do not quote me on that because I don't deal with BornShell as often as I do bash. I might be misremembering. And of course, whenever I say BornShell, I'm referring to a BornShell derivative, not literally the original, the OG BornShell. Who has that these days? Who just has that installed casually? Anyway. So, this while read loop is infinitely executing, notice that the condition is true. So, it's always going to be executing. It's like, as long as the condition is true, execute. So, the condition is always true because this is true. So, if you see what I mean. Okay. So, then we got this for loop for current file in this. So, what's going on here? Well, this is form of a variable expansion. And this is what I tend to refer to as substring removal, I think I refer to it as. This is basically stripping the forward slash, because I am adding a forward slash here. So, just in case the user does provide something with a forward slash at the end of it, I needed to handle that. Otherwise, it would be an error. Because of course, there is no forward slash forward slash. If that makes sense. I'm using globfile in pattern matching. So, this is essentially going over each of the current file becomes each one of the images basically. So, we check the image is exist and is a file. And if not, we continue to the next iteration in the loop. How are you with your for loops? I know they exist. Oh, okay. Well, okay. I could go over for loops. I don't mind. I've used them a couple of times. But it's the variable expansion thing that you were talking about that threw me for a loop. Oh, at this part? Yeah. Okay. What does it mean for variable expansion? Explain that part. Because the idea of variable expansion is it changes what it is expanded to. It doesn't reassign that variable. So, if you have value is equal to one, the number one, and then you call that value and you do something fancy here with variable expansion to get rid of that one and it becomes an empty value, you haven't reassigned. You've only changed how it's expanded. Are you with me so far? What do you mean expanded? I'm showing my enumeness here. I don't know what it is. It's okay. It's okay. You mean because usually music. Bear with me. So, value is equal to one. Now, when I call that value with a variable with a variable, sorry, I'll call the variable with echo or something. That then, it doesn't, I don't know if technically expand is the correct word here because it's not expanded in the same way that brace expansion is expanded. But I might be getting a little bit too pedantic with the word choices here. But let's just say to make things a bit easier, that it is expanded. So, this then becomes one because we know that the value, that this variable, we know that variables, they store values, they store data basically and you can call them all that kind of stuff. So, in that sense, it's expanded to the value of one. So, when I echo one, sorry, if I echo value, the shell will just see that as echo one. That's why we get echo one. That's a general gist of it. Okay. I think I was taking the word expansion to literally less because usually we need to say expansion means to grow bigger, right? So, it's something in my mind. Yeah. See, my mind just went in the wrong direction. That's okay. It's understandable. You're looking at it from an English perspective as a writer and that makes sense. Yeah, like I said, not a programmer. Okay. So, I'll continue with this one example just for this. So, let's say the user enters a directory. They want this program to get images from and actually fable and set those backgrounds based on those images. So, let's say the user runs something like facelides. I can't remember what the syntax for this program is because it's so long since I've used it, but let's say it's something like you just put the file name here or the directory here. So, desktop images, for example. But the user puts an extra forest hash at the end of it. Well, the facelides is clever here because it's using this, which is a form of variable expansion. So, that is getting rid of the last part of it. It's removing this. But it's not reassigning the important part to remember a favorite expansion. It is that unless you specifically tell it to, that is a way. But in this case and in most cases, it is not reassigning that variable. It is not going one equals that without the forest hash. It's not reassigning. It's just changing how it's expanded in that moment. Oh, mind blown. I understand that now. Yes. Woo. Oh, I'm so happy that you got that. Yeah. All right. So, let me see if I can re-explain it to you just to see if I got it. So, basically, it's taking the variable, putting it in that slot, and then removing the slash. But this variable stays the same so that it can be used elsewhere. Right? Yes. Yeah. Like, even though in this particular case, it's going to remove that forest hash, but elsewhere, it's still the same original variable it was. Thus, it wasn't reassigned. Total win. That's awesome. I'm so happy. I thought I'd butchered the explanation. I was in my mind. I was thinking, oh, my God, he's not going to get this. This makes no sense. I've always thought that the whole light bulb moment thing was like a metaphor, but I literally felt the light bulb come on. Like, oh, I understand now. Yeah. That's great. Okay. You can continue on with the script now. I'm sure I'll get confused somewhere else, but I understand that part now. I'm glad. I'm glad you stopped me to get me to clarify that. That's brilliant. I'll probably help people as well watching this video. So, blah, blah, blah, blah, blah, blah, blah, blah. I'm in pattern machine, blah, blah, blah. Now we have this test. I already explained that, didn't I? Okay. So there's this if statement. We have a negation operator here, which was a bang or an exclamation mark. And remember, with an if statement, it's just a command. It's usually just a command. It isn't technically always a command, depending on how you want to see a command. Again, I get quite pedantic. But essentially, the if statement, all that does is test for the exit status of what you put in that condition part. And that condition part, by the way, is pretty much the same as that of those loops, or can be. So, for example, here, I've got a command. I've got an actual program fairly running, and I'm checking for that exit status. So if this exit status is not true, then this will execute. If this condition doesn't do what I'm testing for, then this will be tested. And then this will be executed. If that makes sense, are you with me? Okay. So that was just the logic part of it. What is it actually doing? So Faye is, I don't know what that is. I think that's to say, don't use a certain kind of special file. This is what actually sets the background as center centered. And this is the file. So this, the current file that that for loop is iterating over. So this is basically setting that background. But if that fails, then we get this, the error message. This is just using a function. I always have my own little error function. It makes life so much easier. It makes dealing with error messages much easier. Easier to read, easier to deal with. So yeah, that's basically just setting an image. I'm just, I'm not, I'm just not sure what I'm doing with regards to sleeping because it kind of looks like it's just setting them all in one here. So we do have a sleep here though. So if the image fail, oh, so, all right. Okay. I did write this in a little bit of a strange way. I do apologize. So if this succeeds, we do set the background, then this condition is no longer valid. So therefore we test for this, but these commands are still run, whether they fail or succeed or whatever, whether the condition is true or false, these commands still will execute. So therefore we do change this background. Hopefully it succeeds. And if it does succeed, then we then, then we sleep for this, a given interval. And we do away with the output and stuff. And that's the general gist of that script. That's, that's the main part of it. Okay. That's really cool. So it's, so, because it's in the while loop, so it's going to go over and over again because it's always true. And then it's just going to run through all the images or whatever in the file that the user gives it over and over until it gets to like the, does it, does it loop or does it just go to the end? Well, because of the while loop re-executing this for loop, it is an effect going over each one of the files over and over and over again. If I didn't have the while loop, it would just run through each one of the files in that directory. Each one of the files, but once. But yeah, and then it would quit. So that's why the while loop, okay. Yeah, I understand that. That's cool. That, that was it, like, like eight or nine lines of code. I learned so much in that. Yeah, it's amazing, it's amazing how much you can learn from such a small amount of code. Okay. That was, that was really, that was really good. Cool. All right. I feel like we've, let's see, we have questions in the... Yeah, I was just looking at chat as well. I'm sure we probably did. I am a great teacher, apparently. Oh, I've always wondered. You definitely are. Hey, if I can learn something, you taught me well, because I'm very dense. I have actually, it's funny that there has been a comment or two about me doing some kind of courses. And I have thought about that many times about actually really taking this stuff seriously and hosting a website and, you know, charging a small fee for courses and doing all that kind of stuff. So maybe one day you will see that and you'll get private tuition. You never know. That'd be awesome. I'd pay for that. I wish I had something like that when I was younger. Well, not when I was younger, when I was new to this stuff, which I suppose technically was when I was younger. I just really, like, remind you from our conversation yesterday that I am older than you, so... Oh, yeah. Yeah, that's right. I'm the old man in this conversation. Old man. Yes. Yeah, I'm a young whippersnapper. You two mix it so hard to go actually back and chat and find things. Yeah. So when you run this script, you have to pass it a directory and that input is one. Yes, Xenia, you got it right. Remember the one, that dollar sign one, that's the first positional parameter. That is the first argument the user gives. So if you put in face slides and then put in something, it's that something that becomes the first positional parameter. Okay, so Drishal, I think I can't, I'm probably brushing your name, said I would also like to learn about bash functions. Oh, okay. That's cool. I could go over that if you'd like. Yeah, go ahead. Okay, do the next. This took a totally different path than I thought it would, but I'm loving it. It's basically like doing my regular videos, but I'm actually having life prompts and this is great. This is so much better than doing my usual videos. If we just went over one of my scripts, it would have been, I don't know, kind of boring. So bash functions, school us TFL. Okay. So once again, the usual shebang, I'm only doing that just, I'm forced to have it, I guess. It's not always technically needed, but that's a whole other story for another day. Okay, so functions, there's a few ways to write a function you can say, actually I've never used this method, so I could be wrong here, but I'm pretty sure it's function and then you've got the name or word, as Shell would see it, that being the synopsis or the syntax. So function, word, and I believe it's just that, the open braces and closing braces. And by the way, it's just so clear, they're not called squiggly brackets. They're called braces, okay? I call them squiggly brackets, okay? I can't help it. It's the way it works. Okay. I'll just pretend that I didn't hear it. So function, word, I really hope I have the syntax right. Usually I just do, no, I am missing. I thought that looked a bit empty. Okay, there is a certain thing here. So usually I do that. That's perfectly fine way of declaring a function. But if you put function, I believe you can get away with not using the parentheses. And the parentheses, it's kind of weird that we have parentheses because they don't seem to ever do anything. I don't think you ever can put anything between those parentheses. Like you can in languages like Perl, so I find that really strange. But anyway, that is one way. And I believe you can do that. I guess I could quickly test this just to make sure I'm not speaking poopins as my dad would say. So function, word, and let's just admit the stuff and say echo high. And that's the next out. So that's a one-liner version of doing it. And remember, if you're ever confused about one-liners, you see a semi-colon hash or the shell will interpret that as a new line. Just in case. So now I should be able to put in word. There we go. Okay, so I had the right idea. If you use this function, I believe that's called a keyword. So if you use that function keyword, you can get away with not bothering to use the parentheses. Or you can put in word, then the parentheses, and simply go ahead and do that. Then I can put the word again, and then there we go. So those are two ways of declaring a function. I think I would recommend this one because it just saves your type and function, but use whatever helps you to learn it. Cool. The only place I've ever used functions would be in a BashRC file, so that you can do something similar to... After the aliases that I used those. Oh, yeah, yeah. But I don't even... I was looking at my old BashRC file, and I don't even have those in my BashRC file anymore. I used to have one that I could use to run a script for downloading a YouTube video, I think. But that was back when I first learned... First started editing BashRC files ages ago. Are there any... Can you do anything within a function? Is there any limitations? Are there any limitations to what you can do inside of a function? Well, there is one really downside to shell programming versus other languages, and that is you can't return an actual value other than something similar to an ex-status, but it's actually a return ex-status.  If you're looking at other languages and then you look at shell programming like in Perl, you can actually return a whole line of text if you like, or an actual function or a reference to something. You can do a lot of cool stuff, but in shell programming, just a digit, and that's it. To add insult to an injury, I believe it's just one to two, five, five, like it is with the ex-status or two, five, six. Somebody can correct me if I'm wrong. I can't remember the exact number. You can... Beyond that, though, to my knowledge, anything you can do elsewhere, you can more or less, within shell programming, you can more or less do within a function. I'm sure there is something I'm overlooking, but never mind. It can also take positional parameters, that is arguments or fields or options, however you want to call it. So that's pretty cool. You can send a load of positional parameters to a function, which can really let you get a lot of really cool dynamic functionality using your functions, just as you would using positional parameters handed to a script. Okay, cool. Let's see here. Somebody asked, again, I'm going to butcher your name. The stream will be uploaded on YouTube as a video. Yes, it will stay up right after this. You can see if you can re-watch this if you want. Somebody asks, what is DevNol? I think they're talking about the script you were just looking at. You had DevNol 2 into end 1. That was that slide thing, wasn't it? Yeah. I'm assuming it's this here. This is the old school, I believe this is probably a BornShell script. Yeah, this is a BornShell script, so I'm limited. There's certain syntax I can't use because it's a BornShell script. And remember, when I say BornShell, I do mean a derivative, not the original OG. So a derivative, in example, might be Dash or Yash, yet another shell. Anyway, what this is doing is it's taking, this is called a file descriptor, I believe, as is this. And this one is referring to standard out. This one is referring to standard error. And by using this redirection operator here, what I'm saying is redirect standard out to DevNol. Some of us know, but DevNol is where data goes to die. Not the one from Stardust. He's a badass. And then we've got standard error that gets redirected to. This is a syntax you use to redirect to another file descriptor rather than a file. So this standard error gets redirected to standard error one. But that might look a bit strange. And it did take me ages to get my head around it, to be honest, back into there. So basically what's going on here is standard. If I remember correctly, it reads it from right to left, which is part of the confusion. So the shell, well, it reads this stuff and right to left, redirection stuff. There's all sorts of underlying priorities and orders and things that makes the whole thing really confusing. But I'll try to avoid that. So first, standard error gets sent to standard out. And then it sees this and it's like, okay, so send standard out to DevNol. But at this point, standard out is also standard error. Now, if I have anything wrong, I'm sure some smarty pants in the comment section will tell me. But I believe that I've always understood that that is how it works. So in layman terms, I'm just sending standard out and standard error to DevNol. And this is the original, the OG way, the BornShell method of doing it in bash. You can do something a bit easier. It's just that. So this lovely little bit here just means standard error and standard out. So it's much easier in bash. That's that. Okay. Someone asked if you would explain your prompt. I believe they're talking about your PS1 prompt.  That's a lot because my prompt says rather... Yeah, that might be a bit too much for us. I could be here a while. It's quite complicated. Let me just ask you this. Why did you change from the one that had the rearranged error? Like it used to have the error that went out and then came back in. You know what I mean? You changed to this. So I was curious why you changed. The one you had right before this one. Some of your older videos. It doesn't matter if you can't remember. Oh, my old prompt. Well, I guess I wanted my prompt to be less obnoxious. The old prompt had a lot of these unicode characters and it was a little... I felt like eventually I felt like it was a little excessive. So I wanted something a bit simpler, a simple arrow pointing right that suffices. And I get this stuff because I'm in a Git repository. So once I'm in a Git repository, I get the output depending on how that Git repository is doing. And then I get a special character here to denote whatever this is talking about. I guess that will have to do. Okay, and I have a question. When you were running like printf earlier in your on command line, did the output, but it also had the props stay on the same line? Why did that do that? Because I've never seen that before. Oh, okay. So printf, hello. Well, there is no new one with unlike echo. So with the echo, a new line character is always added on to the end, unless you otherwise specify, which I believe is the n flag, the case n flag. So with printf, that new line character is not added to the end of it. You always have to add that new line character, of course, if you want it. And when I say a new line character, I mean that. So now it's on a new line, and the prompt can begin again on the next line, as it normally would. But if I do that, well, the prompt is going to start at the end of it because I didn't provide a new line character. So the prompt is doing exactly what it's being told to do. It's just, ZSH handles this properly. But I believe ZSH will actually do like a hello and then put that on the end of it and then you get the prompts on the next line. Yeah, that's why I get confused. Yeah. Oh, yeah, that makes sense. That's one good thing about, I like about ZSH actually. I don't understand. It tells you, it puts that percentage sign there to tell you that it's created a new line on its own, probably, right? Yeah, yeah, that sounds about right. Okay. Yeah, all right. Yeah, you don't have to go through and actually explain your prompt, but maybe that's an idea for a video. For you, that Ron. Yeah, it's a really, it took me a long time to get all that solid. It is quite complicated.  I think I have talked about it before in a video, but I can't remember. Zany says to remind me that I need to be on live chat. I am on live chat. We're just have missed so much. I'm actually having to scroll up. Yeah, me too. That's a thing. That's a nice change. Bruce's Eclectic World, I don't know what you're referring to, isn't this part of scripting? I don't know what you mean, what you're talking about. Let's see here. Yeah, I don't know what he was referring to either.  I'm just telling you, man, it's not my fault. It's not my fault. Yes, I'm going to quote this. Yes, it should, unless Matt accidentally does something. Zany asked a good question. Doesn't it get tricky remembering which directory you're in with just an arrow? I forget. I'm so used to this. I've had it this way for many years. I forget that everyone always sees which directory they're in, but I'm so used to not seeing that because the amazing thing here, Zany, is I know this is unthinkable. This might blow your mind a little bit. You might need to have a breather and just really try to gather your thoughts and re-understand life, try to really get your head around life again. But basically, I remember which directory I'm in. I just remember. I used a brain and remember it. That sounds weird to me. There's no magic. That sounds way too much like work for me. You get used to just keeping a lot. Maybe it's easy for me because of shell programming, so bloody much over the last six odd years because when you're in a shell program, you have to, at least the way I write shell programs, you have to keep an eye on which one you're in, which directory you're in, and also just generally using the terminal all the time. I guess I could just sum up by saying practice. It is just practice. And if I ever do forget, I can just do that, which is easy enough. PWD problems solved. Yeah. So that's one of the reasons why when I use bars, right? Because, I mean, it's obviously a different scenario, but I use bars because I use so many workspaces that if I didn't have the workspaces up on top where I could see which one I'm on, I would forget. So, I mean... To be honest, I hate to say this, but just between you and me, just between us, sometimes I forget which workspace I'm on. It happens quite a lot. Well, you can at least be thankful that you don't use nearly as many workspaces as I do. True. I don't have 20 workspaces, like some man, man. I've added a 10-5. I now have... So, when we started this, I said I had like five, six, seven. I had seven. I'm now up to 12. Wow. There was literally just while we're sitting here, they spawn automatically. It's the way it is. I've just spotted another question. Judicial Bellaney said, how did you get the git status in my prompt? So... Oops, wrong place. So, I won't go obviously into huge amounts of detail here, but the git status command is actually used as far as passing what is needed to get the data which is needed to determine what to put on the prompt, if that makes any sense at all. So, how do I get the git status stuff? Well, I've run git status. I guess I need to explain that, but there you go. Yeah, that's something you have to do in Bash. But you have to define that in Bash to actually get it, I think. But in CSH it does it automatically, so... Oh, there's another good question. Wow, you guys are great. So, Analytical Minded said, is... So, anything sent to Devno is deleted. Data doesn't get stored there because I don't want 15 gigabytes of data like Matt. Hey, hey, that was a good story. I can tell my children. That's going to be okay. Don't do as your old man said did, okay? Don't do as I say, not as I do. Go ahead and answer the question. Yeah, it's... To my knowledge, it's gone. It's really gone. It's actually not a file. It's a special file. It's kind of... I'm not sure what the correct word. I guess you could call it a device. I'm pretty sure you could call it a device. So, it is just masquerading as a file, I guess you could say. Yes, what you put there, as far as I know, does die. It truly dies.  It's not where code goes to sit for a while until you decide to recover it. It's where code goes to die. If there is a way of recovering it, I have never heard of it in all of these six or seven years. Okay, apparently Bruce's Analytical Mind was talking, asking if this entire video is about scripting. Yes, it is all about scripting. Oh, yeah, yeah. Hands on like it stuff. Maybe eventually TFL and I will do a video stream where we talk about everything but scripting. Yeah, I'm not sure what we would cover, but yeah. For the first one, it would have felt like a travesty not to talk about bad scripting because, I mean, he has a reputation to protect. I've been reminded. If Matt could have hundreds of workspaces, he would. That's a true story. I was telling TFL before we started that I'm looking for a third monitor and that's going to give me nine more workspaces and I'm really looking forward to it. Wow. Do you another layout, the tile layout and I3 window manager? I don't. I think they might be asking you if, I mean, I'm assuming maybe they're asking why you always have the windows spawn one on top of the other instead of side by side. I've always wondered that. Did we lose TFL? Oh, sorry. I was trying to scroll. I was like looking at chat, basically, trying to scroll up. I thought maybe you're talking to Matt. What was it you said? All right. Somebody asked you something about your workspaces and I didn't quite understand what they were asking, but I've always wondered why you have an I3 while you have your windows spawn on top of each other instead of side by side, which is the default. Oh, no. They spawn side by side or, yeah, side by side. Basically, windows are tiled by default. I have my terminal floating right now. I'm assuming that's what they mean by floating tiled and all that kind of stuff. But yeah, everything isn't tiled. Well, technically, everything is float by default. I actually just talked about this in a video I just put up, but yeah. I paid attention. So that's all covered in that. Sure, sure. I'll try. I'll do my best. That's all covered in that video. Okay. Let's see here. Do you use another layout other than tiled and I3 with a manager? So he did explain the white float stuff in the video he did this morning. Well, I don't use layered or whatever that thing is called. All I use is tiled and float. That's it.  Tabs and I3, when I first found that, I was like, oh, it's so good, because it's like making your, it's like doubling your workspace. Like you can have more workspaces. It was so good. And when I came to DWM, I was like, oh, I'm going to miss the tabs. But if you use monocle mode in DWM, it's basically tabs. You just don't get the titles at the top. So you need like WA workspaces anonymous. I can't. My favorite things about Linux have to be workspaces and key cords. I love those two things. Wow. I'm obsessed with them. I can't help it. And the thing is, is they tell me that the reason why I should use Emacs is because all their key bindings are key cords in Emacs. But I can never get my head around Emacs enough to actually use it. Then I'm too attached to them. So rust programming string when? Well, I don't know any rust at all. TFL, do you know rust at all? No, I'm not just impressed. You'll have to look at this or something else. I know that's a meme now where we write everything in rust. Yeah. Maybe I got to learn bash first and then maybe some Python and then maybe I'll get some rust in me. I don't know. That's a long ways down the road. I tend to just stick with so-called interpretive languages. And I'm not really interested. I mean, there's low-level compiling languages. Sure, they're really cool and everything like that. And there's certain you can do tons more. But oh, my lord, the amount of effort and the amount of time you have to put into just to get simple stuff done. Nope, I nope out at that point. Dricia, I'll ask why I haven't tried Doom Emacs. As Doom Emacs is the one that I have installed, I just haven't got into it nearly as much. My problem with Emacs is that it just does too much stuff. You know, it makes me feel lost. Did you know you can play Tetris inside Emacs? Like, by default. Oh, that's cool. Wow. That gets cool, but it does a ton of stuff like that. I mean, it's weird. I could understand if you could add that functionality, but the fact that it's there by default, it's really weird. Somebody asked if you could explain case statements. Yeah, I was just looking at that. Okay. Well, can I explain if statements first? Because I think that'll make it easier to understand case statements. Yeah, go ahead. I'm sure I'll learn something just no matter where you start. Okay. So at the beginning of time, okay, that might be too far back, okay, views have been environment on bash because reasons. And so if condition, then fee, which I thought that was done for a second, and then commands. So that's the synopsis of an if statement. Did I cover this a second ago or am I just having flashbacks of that video I tried making? I think you did the while loops in this way. Oh, okay. All right. So yeah, if condition then commands, well the case statement, and I'm going to skip tell a little bit. So remember you've got it LF. So LF condition, then commands. And you can have numerous numbers of LF even. And then you can have the final one, which is else. So you don't need special condition here. That's for LF. So else, if none of these are valid, then commands. So let's run through this. If this condition is true, then execute commands. But if this condition is not true, then try this. If that condition is true, then run commands. But if this condition is not true, then we look at these and they just execute regardless. Because there's no extra condition here. So that's the general gist of an if statement. And remember much like a while loop and all that kind of stuff. This is, as I said earlier, just it's just testing for exit status as already. I don't know if it do a return status, but generally speaking, it's just checking for status. There's no magic going on. Like some people think that this is special syntax for an if statement, but it's really not. It's just its own thing really. It just happens that it goes well with an if statement. Anyway, so that is an if statement. Now a case statement is essentially a nicer way of writing an if statement and can be really, really flexible and useful. So case word in pattern one and then commands. And you always have to end that with the two semicons and then got pattern two and then commands ending with the two semicolons. And then you can optionally have something like check for a null value. This is actually a little trick here to check for an empty value. So if word is empty. And when I say word here, I'm on about the shell's idea of a word. So that can be like literally a thing. Imagine I talk that properly or it could be a variable. And just as an extra little note, word spitting doesn't apply here. So if you have a var that happens to be equal to two words, that's not going to mean two words. It's the shell is going to be intelligent there. Sometimes it's not. This is one of those times when it is anyway. So for case word, and then we've got this. So if the word is empty, then do this. Now this is a special way of doing it. You cannot just do that and call it a day because that's the syntax error even in bash, unfortunately. And you then, after all is said and done, you might want to check for if it's anything else. Glob, just like in regex or similar to regex, will be nothing or something. So that this will actually match this. That's why you have to put this first if you are wanting to match for that as well as this. Anyway, so if it's neither of these, if word is not equal to any of those things, then execute commands. And we end in a case statement with esac, case reversed basically. So you can put any number of these pattern thingies here if you want to hold different patterns. And by the way, this is glob pattern matching, not glob far name pattern matching, just so that you know. And you have to make sure that you do not quote the special glob characters. Otherwise the shell cannot properly interpret them because the globbing is part of shell. So you cannot quote protect those. You can quote protect some other stuff. So for example, if I wanted to say home and then something, I can't just go ahead and quote the whole lot because this special glob character needs to be interpreted. And this is, I might have missed that. This is not for glob far name pattern matching. It's just imagine like word is home. I might be going off on one here. But anyway, that's the statement. And then if statement hopefully that helps. Okay, so you'd use a case statement in like for script that requires a user input of something. If the user inputted this and then do this, if the user inputted. You can do, yeah. Yeah, all right. Yeah, that's what you don't, you're not restricted to use it like that. You can use it anywhere really. But yes, that is a very good way of doing it. And one of the reasons why, if I just bring up that case and synopsis, he type thing again, is because one of the reasons why you've probably seen maybe Zane or me do this, is you can say or. So this is really cool. You can have this or here, which means match this or this or that. Yes, you can use numerous ones. It's really cool. And each one of these little things here is just glob pattern matching. So that's really cool. And if you need help with glob pattern matching, I did a video on that quite recently, I think on specifically glob pattern matching. So if it matches any one of these, then execute commands, which is just amazingly useful that you can do that. That's one of the best things about a case statement, I think. Okay, so Ian asked the difference between a single square bracket and double square bracket in if statements. Okay, well, as I said earlier, this and this is not special to if statements. So I'm just going to talk about them in general. They're not specific to a statement. But this of course will apply to an if statement. So this and this, they basically, this is like the OG, the single bracket, the double bracket is a bash thing. The single bracket, there are a lot of details to these things, but I'll cover some of the highlights. So the single bracket, it's a little bit stricter. So if I were to just test for say, home be equal to the value of this, which would be valid in my case, then this would return true. Remember, this is just a command. This is actually just part of the shell. Anyway, it's so, I believe it's a built-in action. Don't quote me on that. So one of the drawbacks of this type is that you will have to quote this, but one of the great things about this particular kind of thing is that you don't have to quote protect that because word splitting does not apply. This is one of those situations in which word splitting does not apply, which is pretty cool. So you don't have to go like this because again, word splitting does not apply. There are several times when word splitting does not apply. This is one of them. I love it. Okay, so this is that one particular thing. Another thing is that this kind of test will actually allow you to do glob pattern, not glob var name pattern matching, but glob pattern matching, which is incredibly useful. So you can have word, sorry, match equals, sorry, wrong around that today. It's word equals match, which is great where that match would be glob pattern matching. So that's amazing being able to have all of that ability in that thingy. But guys and girls, I guess even better than that. Matt, you love this. I'm sure you already know about it, but whatever I'll say it again because I love this on my favorite features. Reg X. Actual Reg X right there in the shell. And that's one of the reasons why that double bracketed test thing is fan bloody tastic because you just have Reg X right there. But once again, like that case statement, remember not to quote protect those special characters because the shell needs to interpret that. So that's just a couple of examples. There are tons of other things. Precedence comes to mind a lot. Certain syntax varies a little bit, but those are just two examples. There will be too much to go through right now. You would be sick of hearing my voice if I went through all of them. Okay, the next one, ZSH and Bash have different globbing syntax, right? I believe so. I think ZSH has extra globbing features. But Bill, I'm just guessing. It's been a while since we've seen ZSH. I think I looked at it recently and did find out that ZSH had some additional globbing functionality. Yeah, I think and Grishal also asks if ZSH has Reg X. I'm positive. I imagine it does. The differences between Bash and ZSH aren't all that much. It's just ZSH adds a lot of the stuff that you'd have to build into Bash. Things that Shopt does in Bash is done by default in ZSH. So it's basically the difference. It does a few things otherwise, but you can run Bash scripts in ZSH basically just the way it is. Not necessarily. And most of my scripts will break instead of ZSH. The biggest difference is built-ins. This is one of the fundamental reasons why I ditched ZSH and did not. This is why I'm not making a tutorial videos about ZSH scripting because Bash is the way it's at. That's the common denominator, I suppose you can say. And when you look at these built-ins, as you can tell, the way I program in Bash and in general is I use a lot of built-ins. I like to avoid using external programs. Why use all these other programs, loading up the whole entire programs when I can just use the shell itself, the thing which is actually loading the program in the first place. So with that in mind, ZSH's built-ins differ greatly in some cases to Bash, even born shell. So that can be a deal breaker. Okay. The reason why I assumed that they would run fine is because I've ran several of your scripts in ZSH and they work, like AutoExec works fine. The your thumb, yeah. Oh, yeah, but you're not actually running it. Remember, there's the AutoExec program. Probably has Bash in the beginning, right? Yeah. Yeah. That's the shebang as Bash. So even though you're in ZSH or ZSH, session, you're still running AutoExec like that, or if you're elite like that. But that is that the kernel is still looking at that part on the screen. So we need to execute Bash. Probably the ones that run fine probably have the same shebang. Is it probably where I got confused? Because like your thumbnail one that you used to create thumbnail, I've ran that one before in ZSH as well. But I'm assuming that has the same. Yeah, that's still bad. That's everything I have is either Perl, Bash, or Bonchelle. Okay. Take a couple more and then we can wrap this up for the day. Alan asks, could you show everyone the difference in syntax for iterating with a for and while loop? I don't know what that means, but maybe you do. Well, the difference between a for loop really, I mean, let's put in the old shebang here, which I absolutely don't need to do, but just why not. So we've got four word in list, do, done. Or if you're super cool and you're in Bash, then you can do it that way. And then you can say commands. Whereas in all the while loop, it's while condition to done. Unfortunately, you can't do the brace trick with while loops and until loops, sadly. And then you've got commands. So the difference here is provided this condition is true, these commands are going to execute. But the for loop, or at least this kind of for loop, is only going to iterate over everything in that list. Once it's finished with that list, you're done. That's it. You're out. You're out. You know, it's done with it, but it's going to execute those commands for every single item in that list. This allows you to do something with word, which is each one of the items in that list, depending on iteration of that for loop. Whereas the condition, there is no word, unless you somehow assign one somewhere. Hopefully that helps. Okay. Drashal asked a big question. What are built-ins? Okay. So you have the shell and then you've got like mini little programs. If you actually look at the source for bash and probably ZSH and stuff, you'll see that there are these little mini programs. And in bash, I can actually run enable s, which will list all of the currently enabled built-ins. Something might have something like this, which will show the actual built-ins. Anyway, so these are the built-ins in bash, at least in my bash. And these are little mini programs. You can think of them a little bit, like this is way over simplifying, but you can think of it a little bit, like functions in your bash setup. They're not like mini programs in a way. Well, that's kind of what built-ins are all about. They are like mini programs. And the idea of calling the built-ins is that they are built into the shell. Okay. Cool. Let's see here. I think we made it to the end of all the questions. Awesome. Yeah. Man, we put TFL through a workout, guys. Yeah, seriously. You put it between my faces. Your fingers are bleeding. It's not my fingers. It's actually my voice. It's my throat that's taking and punishing. My fingers are fine. All right. So I think what we'll do is, we'll just wrap that up there. We went for a good hour and a half, so not bad at all. That's usually about the length of my stream. So yeah. So TFL, Terminal for Life, make sure you check out his channel. The link is in the video description below. He has tons of this stuff on his channel, so you definitely need to go subscribe. Just past 4,000 subscribers. We're kind of in a neck-and-neck race for the first 200,000. Yeah, so get us to 100,000. We'll do another live stream. All right. Yeah. That'd be nice. Anyways, so thank you, TFL, for doing this. This was a lot of fun. I learned a lot of stuff that I did not come over before. So we'll definitely have to get together and do this. Again, we'll try to be more organized about it then. So thanks everybody for watching. Before I go, I should take a moment to thank my current patrons, if I can actually switch to the proper screen. Screen? Pop it to the top of screen. That went really weird there for a minute. All right. Devon, Chris, East Coast Web, Jento, it's fun too. Marcus, Megalyn, Sven, Jax, and I have a tool, Joshua, Lee, Mitchell, Mr. Fox Art Center, American Camp. Thanks everybody for watching. We'll be back with another regular stream next week, and we'll see you then. See ya. Awesome.


This paper proposes a new approach to detect the pre-disease state of complex diseases using a single sample. The authors propose a novel index called Single Sample Cullback Leibler Divergence, SKLD, to measure the disturbance caused by a case sample on the background. This index can be used to identify the critical state or tipping point of a biological system. The authors tested their method on several different types of cancer and found that it successfully identified the pre-disease state of these diseases. Furthermore, they also provided a set of SKLD signaling markers that could be used for further practical applications. This article was authored by Jiu Yun Zhong, Rui Liu, and Pei Chen.


One of the interesting things about mathematics is that mathematics spawns more mathematics, and in the case of the quadratic formula, this is centered around something called the discriminant. So let's review that, our quadratic formula, if I have a quadratic equation, I can find the solutions using the quadratic formula negative b plus or minus squared b squared minus 4ac, the whole thing over to a. Now notice that in this particular equation, this formula, there's two potential problem areas. First of all, because it's a quotient, we're dividing by 2a, we have to make sure that 2a can't be equal to zero. Now this is only going to occur if a is equal to zero, and if we actually have a quadratic, if we actually have a square term, that means a is not zero. Which means that we don't really have to worry about this, 2a is not going to be zero. But in another way, if you ever run into a problem where 2a is zero, you're not dealing with the quadratic, and the quadratic formula doesn't really apply. The bigger problem is we're taking the square root of this quantity, b squared minus 4ac, and because we're taking a square root, we need this number to be a positive number. You cannot take the square root of a negative number, or can you? Well, we'll see about that. But for right now, we need that square root, we need that radicand b squared minus 4ac to be positive. And sometimes it's not going to be. And because of that, this expression b squared minus 4ac is called the discriminant of the quadratic formula. Now if you continue to study mathematics, you'll look at other discriminants, so we do want to be specific here, this is the discriminant for the quadratic formula. And whether this is positive or negative or zero, it's going to tell us something about the solutions to our quadratic equation. So there's three important cases. So if b squared minus 4ac is positive, then this is a real number, and we actually get two real solutions, x equals this, x equals that. If it's zero, then the square root is also going to be zero, and I'll have two solutions again, negative v plus zero over 2a, negative v minus zero over 2a, except these are the same number. When I add or subtract zero, I get the same thing. And so while there are two solutions, they happen to be the same thing. And so we say there's one distinct real solution. And then finally, if b squared minus 4ac is negative, this isn't a real number, and so I have no real solutions. For example, let's say I have the quadratic x squared minus 5x plus 12. Well, I could compute the discriminant only, but we might as well find the actual solution. There's no harm in computing it, and it's good practice using the quadratic formula, which you want to memorize in any case. So we have our quadratic formula, where again a is the coefficient of x squared, that's 1, b is the coefficient of x, that's negative 5, c is the constant that's plus 12, so I can substitute those into the quadratic formula, b negative 5, negative 5, a1, c12, a1, and I get this nice little expression, which I can evaluate using the operations of integer arithmetic, that's 5, plus or minus square root of 25 minus 48, and after all the dust settles, 5 plus or minus square root of, uh oh, negative 23 is our square root. And since square root of negative 23 is not a real number, there are no real solutions. The solutions involve this, what is this square root of negative? Well, I'll have to take a look at that a little bit later on, but it's not a real number. Well, this also translates into geometric problems, find the x intercepts of the graph, and let's take a look at that. So again, if I want to find the x intercepts of the graph, I am looking at points on the x axis, and if I'm on the x axis, the y coordinate is zero. So we're looking for the x values when y is equal to zero. So if y is zero, there it is. I want to know the x values that will make this equation true. Well, that's a quadratic equation. So in order for these points to correspond to real points, it's necessary that those x coordinates actually be real numbers. So let's go ahead and substitute that in. So there's my quadratic equation, y zero equals 12 minus 5x minus 3x squared. A is the coefficient of x squared. Notice that I can use a negative coefficient. That's not a problem. B, coefficient of x, negative 5, c, constant, that's going to be 12, and so I can fill the quadratic formula in x equals negative b plus or minus squared, b squared minus 4ac, all over 2 times a. And so after the dust settles here, this is going to be 5 plus or minus squared 169 over negative 6, and squared 169 is actually a real number. Square root only makes sense if I'm taking the square root of a positive number. 169 is definitely positive. In fact, squared 169 is 13. So this equation has two real solutions. The graph crosses the x axis twice, once at x 5 plus 13 over negative 6, and the other at 5 minus 13 over negative 6.