2.4.4. Basic shell usage#
Open (a terminal)[sec:open_terminal], if you have not an open terminal already.
Every time you open a terminal, it will automatically run the default shell program,
which is bash on Ubuntu by default.
As explained before, the shell interprets your commands and instructs the kernel to start other programs.
As explained about the Unix philosohy, Linux systems contains many small, simple commands that do one thing and do it well. We will start exploring the most basic usage of the shell here with some simple examples, starting a few basic programs.
The examples in this section will also illustrate how programs often support more advanced features and configuration options, allowing to alter their behavior. These configuration options can be specified by adding additional options after the command. Sometimes the programmers have put in so many options that itâs hard to know which program option gives what effect, so in the next section weâll explore how to look through the built-in manual from within the terminal. Nevertheless, common options of common programs will probably get ingrained into your memory, just by using the terminal often. Just as when you learn a normal language, after some practice you should not need to open the dictionary for every word.
2.4.4.1. Hello terminal!#
As a first example, we will look at the echo command.
As its name suggests, it basically repeats whatever arguments you give it, and prints[1] it back to the terminal:
Letâs try it out. Type the following, and donât forget to press Enter to confirm the command:
$ echo Hello World!
You should see that echo has repeated the words Hello World! in the terminal on a new line after your command.
Once the command has completed, you are presented with a new prompt to enter your next command.
Note
The echo command may seem silly at first sight: why would we want to print something in the terminal that we just typed ourselves a second ago?
As we shall see, echo is often used in scripts that automate shell operations to inform the user of progress or errors.
It can also be used to print the value of variables, just like the âprintâ commands in other programming languages,
or be used to save lines of text in a file.
These are all more advanced topics explained later in the manual.
The words after echo are called arguments (characters or numbers following the program name), which act as input for the echo command.
In fact, in this case the echo command has received two separate arguments,
Hello and World!, since bash treats whitespaces (space, tab, newline) as separators between command and each of its arguments.
The echo command prints all of its arguments in order, also separating them with a single space, so we see the same text in the output.
However, the shell ignores any additional whitespace that separates commands and arguments, so if we enter this:
$ echo Hello World!
the echo command will still just get the same two arguments Hello and World!.
Since it prints the arguments one after the other with just a single space,
the resulting Hello World! will not have the same whitespaces as you wrote in the command line.
We can demarcate an argument with double quotes to force the shell to pass an argument as-is, even if it includes spaces or other special characters that the shell might otherwise process differently. Try out this:
$ echo "Hello World!"
Now the echo command receives a single argument, Hello World!, which it prints to the terminal including all the spaces.
Note that the double quotes were not part of the argument itself, so it doesnât appear in the printed line, they only served to tell bash to include the spaces as part of the input.
Exercise 2.20
How many leading spaces will be printed by each of the following commands? Before you test them, predict what you think the output will be.
$ echo Hello World!
$ echo " Hello World!"
$ echo "Hello World!"
Exercise 2.21
What do you think will happen if you just run echo without any arguments?
Try it out.
Nothing happens
Immediately a new prompt appears
An empty line and then a new prompt appears
An error is shown,
echorequires arguments
2.4.4.2. Starting programs, with optional settings#
One of the most common uses for terminals is run basic commands,
such as core utilities that you can find on nearly any Linux shell,
like echo,
as well as more specialised programs installed on your specific system, like git or even firefox.
When typing a command in the prompt to start a program,
some programs also accept arguments to define optional settings.
Weâll illustrate this with some basic core utilities, date and cal.
As a first example, letâs first look at the basic date command, which without arguments tells you what date it is:
$ date
Fri Jul 16 14:04:02 CEST 2010
The output is fairly self-explanatory, except perhaps the CEST part: this indicates itâs Central European Standard Time.
Many programs, including date, use optional arguments to let the user set configurable options to alter the programâs function once.
On option is set by first having an argument indicating what option to set,
directly followed by an argument that holds the desired value for the option.
The option to set is often indicated by a dash - and a specific single letter (e.g. -a, -R, -d)
or two dashes -- and a specific word (e.g. --help, --force, --all).
Some options act as switches which donât take an additional value but simply tell the program to operate in a different manner.
One particularly interesting option of date is -d, which should be followed by a value for the option.
You can use this option to tell date not to report what time it is today, but also in the future and the past.
You can even instruct it in more or less plain English:
$ date -d "tomorrow"
Sat Jul 17 14:04:13 CEST 2010
$ date -d "yesterday-1 week"
Thu Jul 8 14:04:18 CEST 2010
This example immediately shows you that what seems like an ordinary little command can actually be quite powerful.
Note
Observe that options usually only affect the program once, so if you run date without any arguments again it
should just print out the current date again, as before.
Options donât alter the program for subsequent calls.
You will always have to specify all arguments explicitly when you need them.
Exercise 2.22
Use the date command to find out what day it will be in one year, in 13 months and 3 days, and 17 days ago.
{
"checks": [
{ "type": "compareOutput",
"referenceCommand": "date -d '1 year'",
"studentPattern": "^date\\s+-d\\s+",
"passOnce": true,
"desc": "use date -d to find the date in one year" },
{ "type": "compareOutput",
"referenceCommand": "date -d '13 months and 3 days'",
"studentPattern": "^date\\s+-d\\s+",
"passOnce": true,
"desc": "use date -d to find the date in 13 months and 3 days" },
{ "type": "compareOutput",
"referenceCommand": "date -d '17 days ago'",
"studentPattern": "^date\\s+-d\\s+",
"passOnce": true,
"desc": "use date -d to find the date 17 days ago" }
]
}
Exercise 2.23
Find out what switches date accepts by using the --help switch.
{
"checks": [
{ "type": "commandSucceeded", "pattern": "^date\\s+--help",
"desc": "run date --help" }
]
}
With date, you can can specify relative dates. However, when you want to know on what date the last Sunday of this month will fall, a calendar is much more useful. In Unix , the cal command can be used to find out such things:
$ cal
July 2010
Su Mo Tu We Th Fr Sa
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Note
The cal command does not come installed by default in Ubuntu 22.04 LTS.
If the command does not work on your computer,
you can easily install it using the apt command, or with the Ubuntu Software Center.
If you need a hint, see Section 2.3.2.
Exercise 2.24
The first argument cal takes is the year. Try cal 2000 and cal 2525.
If you specify two arguments, the program understands the first argument to be the month and the second one to be the year.
Use cal on your own Linux installation to check: What day of the week is December 31, 7351?
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
In Unix help pages, optional arguments are often indicated by square brackets, like [this].
For the cal command, the syntax then is:
cal [[month] year]
which tells you that you can specify either nothing, or just the year, or the month followed by the year.
Exercise 2.25
What would happen if you would give the year first, then the month? Try this: cal 2010 12.
No output appear.
It shows an error that 2010 is not a valid month.
It shows 2009 months after the first month of the year 12.
It shows the result for December 2010.
It shows a warning on the format, but also the result for December 2010.
2.4.4.3. History#
A useful part of any shell is the history. The shell keeps a list of all lines you typed in since the shell was started. This has several uses:
You can later consult this log using the
historycommand, which shows you what you previously entered in the prompt in the shell session.You can easily repeat earlier commands, or even modify them before executing them again.
Exercise 2.26
Run echo hi and then cal, and then use history to see both commands listed.
{
"checks": [
{ "type": "commandEvent", "eventType": "builtin.echo",
"match": { "text": "hi" },
"desc": "run echo hi" },
{ "type": "commandEvent", "eventType": "coreutil.cal",
"desc": "run cal" },
{ "type": "stdoutContains", "pattern": "^history$",
"text": "echo hi",
"desc": "history should shows echo hi" },
{ "type": "stdoutContains", "pattern": "^history$",
"text": "cal",
"desc": "history should shows cal" }
]
}
The easiest way of using the history is moving through it using Up and Down. A helpful shortcut is Ctrl-R, which allows you to search in the history. Just start typing the beginning of a command, and it will complete to the last command that matches. Hitting Ctrl-R again cycles through all matches.
Finally, you can also repeat specific commands from your history by using the ! shell built-in command, like this:
!!will repeat the last line.!13will repeat line 13.!-5will repeat the line you entered 5 lines ago.!mowill repeat the last command you entered that started with the stringmo.
Exercise 2.28
Run echo hi and then cal 10 2010 to show the calendar from October 2010.
Now use !1 to repeat the echo command from your history.
Subsequently, run !cal and confirm this repeats the calendar command with the same date arguments.
{
"checks": [
{ "type": "commandEvent", "eventType": "builtin.echo",
"match": { "text": "hi" },
"desc": "run echo hi" },
{ "type": "commandEvent", "eventType": "coreutil.cal",
"match": { "month": 10, "year": 2010 },
"desc": "show calendar of October 2010" },
{ "type": "commandEvent", "eventType": "history.expansion",
"match": { "expanded": "echo hi" },
"desc": "use !1 to repeat echo hi from the history" },
{ "type": "commandEvent", "eventType": "history.expansion",
"match": { "expanded": "cal 10 2010" },
"desc": "use !cal to repeat calendar of October 2010 from the history" }
]
}