Classic: Introduction to Bash Shell Scripting 2025 | HPC Training Series #2

So, what is a shell script? Sam, you aren't, I mean, Al, you're not sharing. Oh, my screen stopped sharing? Oh, wait, no, maybe, I'm sorry, it did the thing. Never mind, you're good.

Okay, great. So, what is a shell script? So, a shell script is a way to create a repeatable workflow. It's a text file with shell commands arranged in a custom sequence.

So, that multiple actions can be triggered at once. A shell script is your own personal command that can function as your own part of the operating system, just like any other command. So, why do we use shell scripts? Well, one reason we use them is to save time, so that we don't need to constantly retype commands.

Another reason we use them is for consistency. So, that a particular chain of actions may be reliably repeated. We're going to go over some scripting resources that you can use after this class.

One is a book called How Linux Works by Brian Ward. It's available as an e-book from Columbia University Libraries and Safari Books online. Also, other resources.

There is a shell and scripting tutorial that's available at linuxcommand.org. Also, there's the advanced Bash scripting guide at this long URL right here. And there are many, many, many others. Just simply Google how to shell script, and you will come up with many URLs on the internet.

So, the system we'll be using for this class is one of the HPC clusters, Insomnia. It's at insomnia.rcs.columbia.edu. You log in with your uni and your uni password. Everyone here should have gotten an email before the class that told you how to connect and give you instructions on how to connect.

So, we're going to take a moment to go over access. If anyone may have gotten the email but ignored it or didn't get the email or had any problems connecting, now is the time to send a private message to any of the HPC members here, and they can assist you while I go over the following review. And this review is mainly included for the benefit of those who will be watching these recorded slides alone afterwards.

So, for Windows, Windows users should be using PowerShell. It's something that's installed by default in current Windows versions, and if it's not installed on your machine, you can download it at this URL here. Now, PowerShell will allow you to use the secure shell command, or SSH.

So, if SSH is not installed in PowerShell already for you, you can download SSH, it's a separate package, at this URL here. For the Mac, it's even simpler because macOS has a version of Unix, which is very similar to Linux, built into it. You can access it through the terminal application.

On the Mac, to reach the terminal, you just simply go to the applications folder, utilities folder, and there is the terminal, and you can double click on it and open up the terminal. Either way, whether you're on a Mac terminal or in Windows PowerShell, if you use the command SSH with your uni at insomnia.rcs.columbia.edu, you will then be able to SSH into insomnia. So, hopefully everyone will have access by now, or if you're having a problem, you have talked to one of our HPC assistants, and I'm going to move on right now.

So, first, we're going to do a quick review of some concepts from part one, and these will be demonstrated shortly. So, first, the shell is something that lets us interact with the computer using text instead of a mouse and icons. The dollar sign is the standard prompt symbol.

Our typing will appear here. PWD stands for print working directory. This command shows us where we are in the operating system.

CD stands for change directory, and this lets us move to a new directory. The dot on the command line, the dot is used to represent the current directory. LS is a command that lets us list the contents of a directory.

Cat, with the name of a file, prints a text file of your choice to the screen. Sort is a command that sorts the lines of a file. Rep prints lines that match a particular pattern.

Echo high. Well, here, the echo command is echoing high to the screen. If you would type something else, like Billy, it would echo Billy to the screen.

Sleep five. Well, the sleep command is something that makes your script pause for a predetermined number of seconds. In this case, it's making a shell script wait for five seconds.

And then man, followed by any command of your choice, will show you the manual page for the command that you specify. So, now we're going to set up the workshop. You should all be logged into Insomnia by now.

And at this point, the format of the class is going to be, I will be reading the slide off of, I'll be reading the slide that's in front of us. And then I will switch to my own terminal and actually do the commands in my terminal. So, the first thing we're going to do is make a directory.

Use the mkdir command to make a directory called workshop. Then we will use the cd command to cd into that workshop directory. And then we will use the copy command, which is cp, with a dash v in it.

And we're going to copy everything that's in this folder path. Insomnia 001, departments, intro series, workshop underscore two. We're going to copy every file that's in there into the current directory.

Which is workshop. So, I'm going to switch to my terminal. And I will make it a little bigger.

Just in case anyone has any problems seeing it. So, that should be fine. If anyone thinks that's too small, just simply holler.

So, first we're going to mkdir workshop. We will cd into workshop. And then we'll do cp dash v, everything from Insomnia 001, departments, intro series, workshop two, anything to right here.

And now we're done. So, now that dash v was not required. If you want to see what it did, just type man cp.

And that will demonstrate the man command. And we'll see what it's for. And again, I will do that myself here.

What happens is the man command will bring up the manual page for cp. And what that does is it shows us all of the many, many possible options you can use with cp. Including what we just used, which was dash v. I should say dash lowercase v, because upper and lowercase does matter on the command line.

And you can see that dash lowercase v stands for verbose, meaning explain what's being done. What that means is that being verbose is what gave us this output. It let us see exactly what was being copied out of workshop underscore two into our directory workshop.

If we had not used the dash lowercase v, the copy would have been successful. But we wouldn't have been able to see on the screen what it was doing. Man is something that can be done with any command, like the ls command or anything else.

It lets you see options. It's a very handy thing to remember while you're learning the command line. So next, we're going to go into some examples.

And we'll be using something called word count. And this is excerpted from a book called data science at the command line by Jaron Jansons. So, the first thing we're going to talk about here are pipes.

Pipes are things that let you connect the output from one command to the input of another. So, what we're going to do is use the cat command to show contents of alice.txt. And we're going to pipe that through a grep of rabbit. So, and to make my screen a little less cluttered, I'm going to type clear, which will automatically blank it.

So, first, if we just do a cat of alice.txt, we'll see it's a very long text file. It's got a lot of stuff in it here. Like so.

So, next, whoops. I made my slide go back to the wrong one here. Good.

So, that's what cat of alice does by itself. Show this to the screen. So, we're going to pipe that through a grep of rabbit.

So, pipe through a grep of rabbit. And what that does is it only gives us the lines of alice.txt that have the word rabbit in them. So, we get this line with rabbit.

We get a line with rabbit hole. We get a line with rabbits. Because rabbits, plural, has rabbit as part of it.

And that's simply what happened. We took the output of one command, alice, piped it through another command. Made it the input of that.

You can keep on combining commands with more pipes. So, now we're going to do the same thing that we just did. But now we're going to pipe it through the sort command.

And we will see what happens. I'll also be frequently using the up and down arrows on my keyboard to go back and forth through my history so that I won't need to retype things all the time. So, now, this is what we just did by going up one.

And if we pipe this additionally through the sort command, here's what happens. What the sort command did was sort this output alphabetically. So, the line that starts with A, A rabbit, comes first instead of being third.

Next, the line that has rabbit that starts with an N came next. Then these two lines with Rs and then last came a line with a T in it. Also, you notice the highlighting is no longer here because the highlighting is part of grep.

But in this piped chain, sort is the last command that executes. And sort does not have that highlighting. Next, we're going to use pipes to do something else.

Now, we're going to pipe a grep of rabbit through TR, which translates characters. So, we're going to use TR to turn every R to a W. And here's what happens when we do that. Instead of sort, we'll use TR to turn every R to a W. And what the effect is, is that we end up sounding a little like Elmer Fudd.

Talking about rabbit holes and stwait on a light tunnel. And I am not going to continue talking like Elmer Fudd throughout the rest of this class. However, that is what TR can do.

Translate characters. So, here every R became a W. TR also can do more things. And again, if you typed man TR, you could see other options for the TR command.

So, next, we're going to use W count, which is an example of a shell script. And that's in your directory. So, we're going to take a look inside by typing cat W count to show it to the screen.

So, when we do that, the most important thing to realize here is don't get worried or confused that you don't understand what everything here is. The important thing to take from this is this. W count is a shell script, but also, it's just a text file.

With commands that are arranged in a certain order that we have determined to get what we want. And that's really the important thing to know at this point. A shell script is just a text file.

And we'll be demonstrating more about that in a moment. So, as a shell script, we can execute this shell script or run it. Because it's a command.

So, let's try it. So, we'll type W count. And that didn't quite work.

Command not found. So, why is the command not found? So, it's not found because, as I said at the beginning of this lesson, a shell script is your own personal command. So, since it's your personal command, the operating system doesn't know about it.

It doesn't know where it is. So, in order for us to run W count, we need to tell the operating system where it is. So, where it is is right here in our current directory.

So, that's represented by the dot. And then after that, and this is simply convention, you put the slash. And now you type W count.

So, now the operating system knows we want to run it. That's right here. And well, that didn't work either.

We've got another error message. So, this is permission denied. So, now, why was the permission denied? We'll take a look at that right now.

So, we're going to use the LS command to do LS dash L on W count. And what happens is this. If we do LS dash L on W count, we see the permissions that are on this file.

W count is a text file. And us, as the owners who've copied this into our directory, we have read and write permissions. Other people who are part of the same group we are in the cluster can read this file, but they can't write to it.

And then yet others who may not be part of any other group, if they somehow were on the cluster, would only be able to read this as well. What's missing is the permission to execute W count. That's what you need.

You need to be able to have execute permissions for a shell script to run. So, how we do that is we use the CH mod command to change permissions on W count. So, we're going to use the command CH mod to add X or execute permissions on to W count.

Once we do that, it will have read, write, and read and execute permissions. So, it's something that will be able to run. So, we will do that right here.

And that's the results of LS dash L. We will add execute permissions to W count. Now, we can see the results of what we just did by, again, using that LS dash L. And we see now this has execute permissions. Also, in most shells, you can tell when something is executable because you may notice the color changed.

Now, some shells may not show the color change, but most will. So, that's another indication that something is executable. So, now that we've given execute permissions to W count, this should work.

And, in fact, it does. And what it does right now, at least, is tell us how it should be used with a file name. And we will be getting to that in a moment.

But for now, just know that this is the result of a working W count file at this point. You can also find out what type of file something is on the command line by using the file command. So, if we use that on W count, we will see file W count.

And it tells us. It's a shell script. POSIX is simply it's a standard.

The same way inches or feet may be a standard of measurement. POSIX is a standard for shell scripts. But it's a POSIX shell script.

But it's still just an ASCII text file. But it's executable. So, even though we made it executable, it's still just a text file.

So, next, we're going to alter the contents of W count. So, the first thing we need to do is choose a text editor. A text editor, think of it as something like, well, I was going to say Microsoft Word for the command line, but it's not always that complex.

Maybe more like Notepad for the command line, depending on what you use. So, in this class, we're going to use something called Nano. And we choose Nano because Nano is really one of the simplest ones to use.

Especially if you're just beginning. I've been a Linux system administrator for decades now. So, I tend to use something called VI, which is much more powerful.

But it's also much more complex. And it takes a while to learn. Emacs, similar, is another text editor.

Which you could have endless arguments about which one is more powerful, VI or Emacs. And we will not go into those arguments here. However, also, Emacs has a lot of options.

And it's not all that user friendly. So, it takes a while to learn. So, my advice for anyone who's taking this class is to stick to Nano.

So, you can get done what you want faster. This URL here has a little Nano cheat sheet to show you all the things that Nano can do. As you'll see in a moment, Nano is a bit more user friendly.

And lends itself towards letting you know what it can do. So, we're going to look inside. We're going to do Nano wcount.

And what we're going to do when we use Nano on it is we're going to take the first line. Which now is showing bin shabang is what we in the computer trade call this. Which is the hashtag plus the exclamation mark.

So, the shabang bin sh is how wcount starts out now. And we're going to change that shabang line to bin bash. So, here Nano wcount.

So, here the first line, the shabang line is bin sh. We're just going to type ba and make it bin bash. And here's where the friendliness of Nano helps you out in the beginning.

Because now we want to write this out to disk. Or save it. So, it's telling us right here, control O is save or write to disk.

So, control O. File name, wcount. Yes, indeed. Just hit return.

We've written that to disk. And now we can get out of Nano by exiting. And that is control X. Okay.

So, that's all we were doing for right now. If we try, even though we've changed the insides of wcount. You can see that it still works.

So, as you use shell scripts, there are different types of shabang lines you might see commonly out there in the wild. Bin sh is one. Bin bash is what we'll be using here in this class.

A bin zsh is a common thing you might see. On the Mac, currently the zsh shell is the default. And it's bash compatible.

So, most things written for bash will run under zsh. And most things written for zsh will run under bash. Other common lines that you may see in scripts are user bin perl.

Perl is another scripting language like bash that is on most command line computers. Perl is a bit more advanced than bash is. But it's pretty common.

Also, user bin python is similar. It is a more advanced scripting language than bash. Which one is more powerful, Perl or Python? That's another thing that can be an endless debate.

And we shall not debate that in this class. I will spare you that. However, these are all some common things that you may see in scripts as you advance your knowledge after this class.

So, has the file type changed from our editing? No. And you can see, even though we've been playing around with the insides and things, if we do a file of wcount, it's still the same old thing that we started out with. And that it's a shell script.

And it's an ascii2 text file. Editing contents does not change the essential nature of the file any more than whether you put on makeup or change your shirt changes the essential makeup of who you are. Now, we're going to talk about variables.

And a variable is a way to assign values that can be reused or altered. So, here, for example, the variable is file. And we set that to be alice.txt. Then if we use echo file, or some may call it string file when you have this symbol in front of it.

But either way, how you call it, this is a variable. And when you echo the variable file, it will show exactly what the contents of the variable was. In this case, Alice.txt. So, here's the example.

Remember, and I'm going to clear my screen so that it's less cluttered. So, remember way back at the beginning, we talked about the echo command. So, if we wanted to echo oops, sorry, I had no touch typist.

If you wanted to echo Alice.txt to the screen, that's how you would do it. Now, if we make file equal to Alice.txt, oops, sorry, again. If we make the variable file equal to Alice.txt, now we can just echo the variable file.

And we get exactly the same result. Because we've just defined that variable to be this value. This can work with all types of values.

This is just, again, a very basic demonstration to get you used to the idea. But there are much more complex things that can be done as you make more shell scripts in your brand new scripting career that you will be launching. So, we're going to continue with the exercise.

So, one thing we're going to do is use nano to replace the second line of wcount. We're change that second line to be file equals Alice.txt. We'll also exit nano. On the command line, we'll type file equals Alice.txt. And we'll try to cat that to the screen instead of using the name.

So, again, we'll use nano. Nano wcount. And we're going to change the second line to say file equals Alice.txt. And we're going to control O. Save this to disk.

And then control X lets us exit nano. And then also, we're going to do this on the command line as another exercise. So, it's file equals Alice.txt. So, if we want to show Alice.txt on the screen, instead of typing cat Alice.txt, we can use the variable that we defined and get the exact oops, we won't.

Not if I don't type it right. And get the exact same result. Variables can also be used with pipes.

So, we can do the same thing with the pipes that we did before. We can cat file. And we can pipe it through a grep of rabbit and pipe it through trrw.

And even though we've used a variable, we get the same result that we got before. So, now we're going to move about something called parameters. And what are they? Well, a parameter is also called an argument.

And that is input we can give to a shell script on the command line that it can use during its run. Parameters are invisible. Every shell script has one or more parameters.

But not every shell script makes use of those parameters. So, I was trying to think of a good analogy for that. One doesn't come to mind right now.

But we will demonstrate this in a moment as we move on. So, the first invisible parameter of a shell script is $1. The second is $2.

The third is $3. And so on and so forth ad infinitum. So, we're going to use parameters to change w count so that any file can be specified from the command line by just using this and a parameter.

So, we're going to go through what we're going to need to do to change this right now. So, in this example, w count will be given parameters of Moby.txt and Alice.txt. They will be the first parameter. So, we're going to use nano to update w count.

And we're going to use $1 instead of Alice.txt. So, we're going to use nano. This is the line as it is right now. And this is the line as it's going to be after we're done.

So, let me show you. And again, I will clear my screen so it is less cluttered. So, we will do nano w count.

Here we are. And right now, this is file equals Alice.txt. So, we're going to change that. And we're going to make it equal to the first parameter that we give the script.

And again, we're going to write this out to disk. Control O. And we're going to exit nano with control X. So, now we're going to try it out. And you'll see the different results you get when you use w count with different parameters.

So, if we use w count now, w count Alice.txt, with a parameter, we can see and actually let me make my screen a little bit bigger. We can see what w count actually does. W count is a program that's going to be counting the number of occurrences of each word in the file.

So, we can see in Alice.txt, the word the occurs 1643 times. And and occurs 872 times inside of that file. But by giving it a parameter, we can change what we're doing with w count and it becomes much more versatile.

Because we don't just need to count the words in Alice.txt. It's going to count by parameters and count the words in any text file we give it. So, we have Moby.txt inside of here. So, if we just change that, dollar sign one is now equal to Moby.txt. And we're counting the occurrences of words in an entirely different file.

That's why variables and parameters are very useful. Because it makes your scripts much more versatile. So, now we're going to do more exercises with parameters.

So, what we're going to do is create a new file named param. We're going to put the shebang directive on the first line. On the next line, we'll type echo dollar sign one.

We'll save it and exit nano. And we'll make it executable. So, we're going to create param nano param.

And we're going to use the shebang. So, remember, that was what we're using here is bin bash. And on the next line, we'll type echo dollar sign one.

And then we're going to save it, exit nano, and make it executable. So, again, write out control O. And then exit control X. And then we will make this executable by doing chmod. In fact, I'll use the LS command again just to show you.

It's a text file. You can see when you use the file command, it is asking you to oh, that's interesting. It shows it is executable even though it's not yet.

Hmm. Live and learn. But it is not executable because we've seen the permissions on this.

So, I do chmod plus X param. Now, when we do the listing, we can see this is now executable. And the color has changed to indicate that.

So, now we've done what we needed to do on this slide. And next, we're going to test it out. We've seen the contents of what the file is.

So, we're going to test it out by doing some example runs. So, if we just do param, we get a blank line. Because, again, this is echoing the first parameter that we gave it.

So, we gave it nothing. So, we got nothing. If we do param with ls.txt, we get ls.txt because that is the parameter of $1.

So, now, let's give it more parameters. Okay. So, what happened here? Why did we give it three and it only came back with $1? Well, that is because we told param to only echo the first parameter, $1.

So, we gave it three parameters. And this became $2 and $3. But we didn't tell it to do anything with $2 and $3.

So, again, you didn't say to do anything with it. You don't get anything done with it. We could have given a long string of parameters.

But since we gave no instructions for what to do with them, they simply are discarded. So, now we're going to play around with param again. We're going to use nano to update it to print out the number of parameters.

And this is what's going to happen. So, we're going to use nano. Nano param.

And what we want to do is instead of echo $1, we're going to use echo $hashtag. So, we just do that. We replace this with a hashtag.

And then we'll write this out to disk. And then we will exit the file. So, now let's do what we were doing before and run this with different parameters.

So, first, we'll do param. I can do a little copy and paste in here. We'll give it no parameters.

Well, this time, we get something a little different. Because what $hashtag is, it represents the number of parameters that we gave to the So, this time, when we ran param with nothing, it comes back with nothing or zero. If we do it with Alice.txt, we see that there is one parameter.

And now if we do the exact same thing that we did before with three parameters, well, this time, it's telling us the number of parameters. So, these extra ones become relevant. And the answer is three.

And, of course, this can go on and on ad infinitum. So, that is what $hashtag represents, the number of parameters that are given to the shell script. So, next, we're going to move to something a little bit more advanced.

We're going to talk about if then statements. So, if then is a conditional statement. A conditional statement is something that lets you test if something is true or false and act differently depending on the outcome.

So, if something, then do something. And the end of every if statement is always the reverse, fee. So, that encloses the entire statement.

So, this is what the general format of an if then statement is. Now, there are different types of comparisons that you can do. A one square brace.

And actually, I should amend that because as we saw, braces come in pairs at the beginning and at the end. So, I should say two square braces, one at the beginning and one at the end is what's called a standard comparison. A double square braces at the beginning and end is what's called an extended comparison.

And there really isn't a lot of difference between the first two, though this is the generally preferred syntax for more technical reasons. But at this level, it's easier if you're doing a square brace comparison to just simply use double ones at the beginning and the end. Now, also, you can do mathematical comparisons with the curved brackets at either end.

Because we can't cover everything here in this class, what we're going to focus on is one type and we're going to be using extended comparisons. So, here's an example of a comparison with square braces with the syntax example. If the variable count is equal to 100.

And there are different types of comparisons that you can do. Dash EQ means equals. Dash NE is not equal.

Dash GT is greater than. And there are many, many, many different types of comparisons that you can use. And there are just simply too many to list here.

Here is a URL that you can go to on the internet that can show you the different types of comparison operators. Also, again, Google is your best friend. You can simply Google for comparison operators in Bash.

You can find many different pages that will explain the concept of comparison operators and also list the many different types you can use to make comparisons. So, we used this earlier in WCount. If the number of parameters is not equal to 1, then echo how to use WCount.

Usage WCount and a file name and then exit the script. And then fee is what ends the if then clause. And we also have something called if as a shell script in our class directory.

And the contents is just the relevant part of WCount. So, again, let's make this less cluttered. And so, if is in our directory.

And this is the relevant part of WCount that we were talking about. If the number of parameters is not equal to 1, echo how to use it and then quit. So, we're going to try this again.

We're going to use if. So, if we just try if by itself, we get how to use it. Because, again, if the number of parameters is not equal to 1, we gave it no parameters.

So, yeah, that's not equal to 1. We echo the usage. Now, if we do oops. If we do if with Alice.txt. Oops.

What do we get? We didn't get anything. So, why didn't we get anything? Well, we shouldn't get anything. Because, again, all this that's in if is only saying if the number of parameters is not equal to 1, then do something.

Well, we gave it one parameter. So, this isn't true. The number of parameters does equal 1. But we didn't say to do anything if the number of parameters equals 1. So, since we didn't say to do anything, nothing got done.

So, this is functioning as intended. And, again, if we use more parameters, we get the same thing as when we started. Because, again, the number of parameters here is 2. So, since 2 is not equal to 1, we get the exact same result that we got in the first place.

So, now we're going to expand on the concept of if then by introducing else. So, if then makes a binary test. If something, then do something.

Else lets us add some alternatives to the test. So, you can make clauses that say if something, then do something. Else, if that's not true, do something else.

So, we could have tested for other things in W count. Meaning, if we if the number of parameters was not equal to 1, we echo the usage. Else, we do something else.

And we're going to demonstrate using else shortly. We're going to talk about some more file tests, though. Other things you can test for in comparisons.

Here's an example. If dash D oops, sorry. I have went a little bit too far with my clicking.

If dash D stands for does a directory exist? So, this is testing for if a directory exists, do something. You can also invert or reverse your tests with the exclamation point. So, what this is saying is if this directory does not exist, there are a lot of different tests, again, that you can do.

And at that earlier URL about comparisons, you will find more information. But other things are you can say if a particular file exists or with the dash E reversed, it would be if a file did not exist. R. And I should actually be specific because upper and lower case does matter on the command line.

So, this is lowercase E, lowercase R in a comparison means if the file exists and it's readable. We've already gone over how lowercase D means if a file exists and it's a directory. And, again, there are many different types of comparisons you can make.

You will find them at the previous URL as you advance in your scripting journey. So, file test is an example of testing for a file's existence. And that's something else we have in our directory.

So, these are the contents. When you use cat of file test, you'll see inside of it, it's file test is testing if a file exists. And what that file is is the first parameter.

So, we're going to tell file test what we're looking for. So, if what we're looking for rather does not exist, then it will say error, that file is not found and exit. Otherwise, else, that file does exist.

And it will say, yay, that exists. So, let's try it with different types of input as the first parameter. So, again, we have file test.

Also, as a quick aside, I'll show you something that I'm doing that's useful, which is called tab expansion. I'm not always typing everything here. I know that there's only one thing in here that starts with an FI.

So, I can just start typing and hit tab and it completes everything for me. That when you know you have unique names inside of a directory, that's a very quick way to expand something and not do a lot of typing. So, I just typed FI and hit tab and that expanded into the name.

It's useful. It won't always work if you have a lot of similar named files, but it's something to be aware of. Anyway, if we cat file test, these are the contents.

We can see, again, if the file does not exist, give us an error. If it does exist, then say, yay, it exists. You can also see that file test, it's already executable, so we don't need to worry about the permissions.

So, let's try it with different inputs. We'll run it right here and CBS.txt, get an error because there is no CBS.txt that's in this directory. There is an Alice.txt. Whoops.

So, it runs and, yes, we get the choice. Yay, the file exists. It's a simple program, but again, it's building on the things that we've talked about already.

Doing a comparison, inverting it to say the opposite. So instead of existing, it's not existing. We're using parameters, and we're using else statements to do different things if the first condition is not satisfied.

So even though it's simple, it builds on the different concepts that we've already talked about in the prior slides. Next, we're going to move on to something else called loops. A for loop is what's called an iteration statement.

For loops allow you to repeat actions a set number of times. And we're going to go over examples of for loops in the next slides. So the general syntax of a for loop is for a variable in a certain range, and you can have more than one lines of something.

And when your lines are exhausted, your conditions are done, you type done. So that this becomes a clause that the entire for loop will do a certain number of times. So we've got a for oops, sorry.

I keep hitting wrong buttons. And okay. So we have a for script in our directory.

It looks like this. For a variable in a range of variables, and this is just three, A, B, and C, echo the variable, and we're done. We've also got a script called 4002 in our directory, which has a different range of variables.

This time it's going to do something in a range of 1 to 10, and this is a shorthand with the curly braces. Curly brace, start of your range, two dots, and then the end of your range. So this basically means 10 times.

So for a variable in 10 times, we're going to repeat the number of times we're through the loop. So actually, let's try those for loops. So clear.

Okay. So this is our script for, and it's for I and A, B, and C, echo the number of times. And it looks like this file actually has some extra things in it from an earlier version of this lesson.

So let's get the extraneous stuff out of here by using nano. So we can just go down here and just delete all of this other stuff because we don't need it. So this backspace.

Okay. That's better. That's how this should look.

So now we're going to write this out to disk, and we're going to exit. Okay. So that's a little bit better.

And let's check our permissions just to be sure. And for is not yet executable. So let's make this executable with chmod.

Okay. Now, that's in better shape. This is executable.

So now let's just run for and there we go. And again, it's doing exactly what we told it. So for I, this is the variable.

For variable in a range, A, B, and C, echo the variable. So the first time through this for loop, the variable I equals A, and A gets echoed to the screen. So we're done.

We go back to the top of the loop. The second time through the loop, the variable I equals B. So B is the value. We go down into the expression of what we want to do, and it's echo the variable.

Well, that variable now equals B, so we echo B to the screen. So we're now done. We go back to the top of the loop.

The next time through, the variable I equals C. So this is the value. What are we going to do with it? We go down into the loop, and we echo the value of that variable, which is C, and C is printed to the screen. And then the computer goes back to the top, sees there's nothing else, it stops, it ends, and we get back to our command line.

So that's the result of for, and this is the contents of for. So let's look at the other script. If we do cat for 002, here are the contents of that, and look at that.

Looks like from an earlier version of the class, this is only as a range of 3 instead of 10. So let's change that. Let's extend our range here.

So this, instead of 3, will be 10. That gives us a bit more of an example. So we'll write this to disk, control O, write out, and control X. Exit.

Let's check the permissions. Look at that. It's not executable.

Well, let's fix that. We will use chmod plus X 402. Now, when we look at the permissions, that's much better shape.

So let's try it. We run right here, 42. OK.

And again, that did exactly what we wanted. So in this range, for i in the range of 1 to 10, well, the very first time through the loop, i equals 1. So we echo repeat 1 times. And we get that.

That's all we do. We go back to the beginning of the loop. Next time, this is shorthand.

So we don't see 2, 3, 4, blah, blah, blah in here, because this shorthand stands for everything in between. The next time, the value is 2. It echoes that value, repeat 2 times, and so on and so forth. At this point, you get the concept of what's going on here.

And this whole do done sequence repeated 10 times, because that's the range that we gave it. A nice little exercise that you can do on your own. See how you could change this so that the very first time, instead of saying 1 times, it would just say 1 time, which would be more grammatically correct.

But that's something that you can do on your own. Again, this is illustrating very basic concepts, building on what we've learned in the previous slides. So now we're going to talk about while loops.

And what are while loops? A while loop is called a control flow statement. These let you perform a specified action only while a certain condition is true or false. So we're going to go through the while loop syntax.

And notice here, we're using a mathematical comparison. So with the while script in our directory, we will come in and first we will set the variable we're using to 7. And what this is going to do is while the variable is greater than 4, we're going to echo that variable. And then we're going to set that variable to be the exact same value it has minus 1. So what we're doing is decrementing the variable.

So the first time through, it will be 7, then it will be 6, then it will be 5 and 4 and so on and so forth. That's what this script is going to do. And, oh, actually, all right.

So let's just stay right here. And let's look at the while script. And we will clear.

And let's first take a look at the permissions before we even go into it. Well, looks like while is not executable either. So let's make it executable because we know we want to use it.

So chmod plus x. While. Okay. That's better.

Now, let's look inside of while. We could have used cat, but I'm just using nano here anyway because why not? And so here we have the while script. Sets the variable to be 7 at the beginning.

And then while this is greater than 4, it's going to do something. All right. So let's test it out.

We didn't change anything. So I just used control x to exit. And just do while.

And there we go. We only get three numbers. Because, remember, we only do something while this variable is greater than 4. So the first time through the loop, this equals 7. So we echo something.

And then we make the variable one less. We decrement it. The next time through this loop, the variable is equal to 6. So while this 6 is greater than 4, we print something.

Then we decrement that. And the next time through the loop, it's 5. So we echo that. We decrement the variable.

The next time through the loop, it's 4. So 4 is equal to 4, not greater than 4. So nothing happens and we drop out and the script ends. So the next thing we're going to talk about are comments. So inside of a shell script, everything the shell encounters after the hashtag mark is ignored.

So in a script, this is a comment. Also, this is a comment. The only exception is the shebang at the start of a script.

That is special. So this is not ignored because it's telling the shell to use bash. Remember, at the beginning, I told you there were different lines you could use depending on what you're doing.

This could be Perl. This could be Python. And this could be ZSH.

So this line at the beginning of a shell script is important. The contents after the hashtag are not ignored. Other than that, though, any time you use a hashtag in a script, everything after that is ignored.

It's very good to use comments. You should always use comments in your scripts. It's very good to be a good scripting citizen and put a comment into your script.

Some reasons are later on, after you make more and more scripts, you will tend to forget exactly what your scripts were doing. So if you make a comment line in your script, you can remind your future self what your past self was thinking of. Or you can say, what the hell was I thinking of? Also, the other reason is that other people at some point may come along and use your scripts.

So by using comment lines saying the following line does this, the following line does that, it will make your scripts more explanatory for other people. Especially, say, if you create a very complex script for your lab to use and eventually you leave the lab or graduate, other people need to use them in the future, comment lines saying what you were doing at different sections are very useful. Without comments, your scripts should be not complete.

So here's some examples in the wild script that we had. You can put a comment in. So you can say that we're doing a mathematical comparison here.

You can also put in a comment line saying echo the variable to the screen and then decrement it. So it's explaining what's here. So this is an example of a better version of the wild script with comments in it to explain to our future selves what was going on.

And this brings us to the end of our allotted time. So I want to open it up to are there any questions anyone has? And if you're lucky, I may even have answers. But if anyone has a question, feel free to chime in right now and I will do my best to answer it.

Well, it looks like there are no questions.

Recorded April 2025

In this workshop, we'll be covering the fundamentals of Bash, a powerful command-line tool used for automating tasks and managing systems in Linux environments. We'll explore why Bash is crucial in high-performance computing (HPC) for automating job submissions and managing resources efficiently. Topics will include basic Bash syntax, variables, control structures, and functions, as well as how to use Bash in conjunction with SLURM for job scheduling and management.

Note: This Intro to Bash Shell Scripting session is simple enough that you can skip the ssh step, and follow along with any computer that has a bash command line and don't need access to an HPC cluster to practice:

  • Macs have bash built-in,accessible via the Terminal application.
  • On Windows, you can install a full Linux environment somewhat easily, for free: Windows SubSystem for Linux 2, available at https://www.omgubuntu.co.uk/how-to-install-wsl2-on-windows-10. Though this installs a Linux distribution slightly different from what is on CUIT's HPC clusters, at the basic level of the two intro classes, it's functionally the same.