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, echo requires 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:

  1. You can later consult this log using the history command, which shows you what you previously entered in the prompt in the shell session.

  2. 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.

Exercise 2.27

Run echo hi and then cal, just to have some command history to look at. Now press Up twice to navigate back to echo hi, but before pressing ENTER change it to echo bye by erasing the last word with Backspace, then run it.

{
  "checks": [
    { "type": "commandEvent", "eventType": "builtin.echo",
      "match": { "text": "hi" },
      "desc": "run echo hi" },
    { "type": "commandEvent", "eventType": "coreutil.cal",
      "desc": "run cal" },
    { "type": "uiEvent", "eventType": "history-navigation",
      "match": { "direction": "up", "command": "echo hi" },
      "desc": "navigate Up to echo hi" },
    { "type": "commandEvent", "eventType": "builtin.echo",
      "match": { "text": "bye" },
      "desc": "change the line to echo bye" }
  ]
}

Finally, you can also repeat specific commands from your history by using the ! shell built-in command, like this:

  • !! will repeat the last line.

  • !13 will repeat line 13.

  • !-5 will repeat the line you entered 5 lines ago.

  • !mo will repeat the last command you entered that started with the string mo.

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" }
  ]
}