---===[ Message from the authors: This wiki might be taken down due to maintenance ]===----
ITIC:Introduction to Bash scripting
What is a script
Remember that Bash is a command line interpreter (a shell). The word line is central here. Bash only processes complete commands if they end with a newline character (typically you press Enter to issue the command for processing by Bash).
Bash can work interactively like this. You enter commands to be processed when you press Enter. But Bash can read files with commands too, and it can read from standard in. Here are some examples of bash working interactively, reading from standard in (using a pipe) and reading from a file called
$ cat file-with-echo echo hej $ echo "echo hej" | bash hej $ bash < file-with-echo hej $ $ cat file-with-echo | bash hej $
In the example above, we started by showing you the contents of the file
cat. The text inside the file was
echo hej. But, hey, that's a valid command line! So if we told bash to read that file from standard in, using redirection and then also a pipe, wouldn't it execute the command line in the file? Yes it would and it did. We can even use
echo and a pipe to
bash to have
bash execute the command from
echo, as you saw in the example:
echo "echo hej" | bash. Bash read
echo hej from standard in, and since it ended with a newline (default behavior from
echo), it just executed it. So we created a new instance of Bash, which executed the command
echo hej and then exited.
You should be aware that in all of the examples above, we are running bash interactively but start a new instance of bash which reads commands and executes them, then dies (so we are back in interactive mode).
But Bash can also execute a file that contains a special first line thing called shebanb and that has execute permissions for the user. Let's look at such a file:
$ cat say_hej.sh #!/bin/bash echo hej
The first line is the shebang and it tells Bash how to execute this file. In fact, the shebang line tells Bash to use Bash to execute it. The rest of the file is just one single command line with
echo hej. By the way, "hej" means "hi" in Swedish.
We named the file
say_hej.sh using the
.sh suffix. Not because we had to, but because it is a shell script, and it's a convention to name such files with the suffix
.sh so that we later can expect the file to be a script, just by looking at its name. As far as Bash is concerned, the file could be called anything, like
say_hej.bananas or even
say_hej.pdf but that makes less sense to us humans. Some operating systems (looking at you, Windows) have put some magic into filenames, letting the suffix decide what file type they are. We, the authors, have never understood how a name can change the contents of a file (it can't, by the way). Just as if Rikard changed his name to Rebecca (which happens to be the name of his sister), it wouldn't make him a woman physically. Or if Henrik changed his name to Rikard, it wouldn't make them the same person. We think that the contents of the file should decide its file type, and so does most reasonable operating systems as well as Bash.
If we had an MP3 file called
say_hej.sh, Bash would not be able to "run" it. Because Bash only understand plain text and command lines. Bash would still be able to tell an MP3 player application like
mpg321 to play the MP3 file, and
mpg321 would still be able to play it (if it really is an MP3 file), regardless of its name ending with
.mp3 or not.
Anyway, files with execute permissions, and a shebang and some command lines are what we call scripts (or Bash scripts if the shebang is exactly
So let's add the execute permission to the file and execute it:
$ chmod u+x say_hej.sh $ ./say_hej.sh hej $
To add execute permission for the user that owns the file, we use
chmod u+x and the file as argument. To execute the file, we need to use a relative path. If we are in the same directory, the relative path will be
./filename, in our case
./say_hej.sh . This has to do with the fact that, if we want to use our script as a command, bash must know where to find the command. Bash uses the environment variable PATH to decide where to look for commands. This is actually a good thing. If we happened to have five programs called
ls in different places on our computer, how would Bash know which one to use? We need the list of directories in the PATH variable to find the correct one. If you want to execute your own
ls program you will have to be explicit about it and give Bash the relative or absolute path to your command. You cannot expect Bash to read your mind and understand that you meant another version of
ls from the standard one in
So, if our script is not in one of the directories listed in our PATH variable, we need to use a relative or absolute path to the script to help Bash find it.
- Bash scripts are just plain text files with command lines
- They can be executed as commands if
- they have the execute permission
- they start with
- we help Bash to find the script using a path to it
Our first script
Let's create a script together. The script should:
- Print a welcome message with you user name and the current time and date
- Print your computer's name and IP address
Now, a script is just a bunch of command lines, right? So we can actually try the command lines in the shell interactively, before we make it into a script. If they work in the shell interactively, they will work in the script.
Before we start, we'll have to tell you a few useful techniques:
- You can tell
echonot to make a newline by using the flag
- You can create text (e.g. for echo to print) by using command substitution:
echo "Today is $(date +%A)"- prints
Today is Mondayif it is Monday
$(date +%A)will be expanded to the result of the command
- Always use quotes around text (will spare you some headache)
- Using a semicolon allows you to issue two commands on the same command line
When trying the commands for our script in the interactive shell, we'll use the following commands:
echo- to print stuff
hostname -I- to get the IP address
uname -n- to get the computer name
And the environment variable $USER contains your username.
$ echo "Welcome $USER" Welcome rikard $ date tis 6 aug 2019 11:30:15 CEST $ echo -n "Your IP address is ";hostname -I Your IP address is 10.0.116.35 192.168.56.1 2001:6b0:2:2801:36bd:fb4f:417b:b503 $ uname -n newdelli $
Feel free to try the same commands yourself. You should get different results, of course.
Now, let's make a script out of those command lines. If you want to follow what we do here, create a directory first and cd to that directory. You don't want to pollute your home directory with a lot of scripts and unrelated files.
Use an editor to create a file called
welcome.sh and put the shebang on the first line of the file. Put the commands in the same order as we tested them in the file and save it. Set the execute permission on the file and execute it with
./welcome.sh. If this is the only file in the directory, you may use tab completion when executing it. Type
./w and press TAB, then enter.
This is what the file looks like when edited using
Summary lecture slides
Videos and video slides
- Video: TODO
- Video slides TODO
Where to go next