Linux Commands

Executing Commands in Linux

A command is an instruction given by a user telling the computer to carry out an action. This could be to run a single program or a group of linked programs. Commands are typically initiated by typing them in at the command line (in a terminal) and then pressing the ENTER key, which passes them to the shell.

The Terminal
The Terminal

A terminal refers to a wrapper program which runs a shell. This used to mean a physical device consisting of little more than a monitor and keyboard. As Unix/Linux systems advanced the terminal concept was abstracted into software. Now we have programs such as LXTerminal (on the Raspberry Pi) which will launch a window in a Graphical User Interface (GUI) which will run a shell into which you can enter commands. Alternatively we can dispense with the GUI all together and simply start at the command line when we boot up.

The shell is a program which actually processes commands and returns output. Every Linux operating system has at least one shell, and most have several. The default shell on most Linux systems is bash.

The Commands

Commands on Linux operating systems are either built-in or external commands. Built-in commands are part of the shell. External commands are either executables (programs written in a programming language and then compiled into an executable binary) or shell scripts.

A command consists of a command name usually followed by one or more sequences of characters that include options and/or arguments. Each of these strings is separated by white space. The general syntax for commands is;

commandname [options] [arguments]

The square brackets indicate that the enclosed items are optional. Commands typically have a few options and utilise arguments. However, there are some commands that do not accept arguments, and a few with no options. As an example we can run the ls command with no options or arguments as follows;

The ls command will list the contents of a directory and in this case the command and the output would be expected to look something like the following;

pi@raspberrypi ~ $ ls
Desktop                   python_games
Options

An option (also referred to as a switch or a flag) is a single-letter code, or sometimes a single word or set of words, that modifies the behaviour of a command. When multiple single-letter options are used, all the letters are placed adjacent to each other (not separated by spaces) and can be in any order. The set of options must usually be preceded by a single hyphen, again with no intervening space.

So again using ls if we introduce the option -l we can show the total files in the directory and subdirectories, the names of the files in the current directory, their permissions, the number of subdirectories in directories listed, the size of the file, and the date of last modification.

The command we execute therefore looks like this;

And so the command (with the -l option) and the output would look like the following;

pi@raspberrypi ~ $ ls -l
total 26
drwxr-xr-x 2 pi pi 4096 Feb 20 08:07 Desktop
drwxrwxr-x 2 pi pi 4096 Jan 27 08:34 python_games

Here we can see quite a radical change in the formatting and content of the returned information.

Arguments

An argument (also called a command line argument) is a file name or other data that is provided to a command in order for the command to use it as an input.

Using ls again we can specify that we wish to list the contents of the python_games directory (which we could see when we ran ls) by using the name of the directory as the argument as follows;

The command (with the python_games argument) and the output would look like the following (actually I removed quite a few files to make it a bit more readable);

pi@raspberrypi ~ $ ls  python_games
4row_arrow.png           gem4.png                    pentomino.py
4row_black.png           gem5.png                    pinkgirl.png
4row_board.png           gem6.png                    Plain_Block.png
4row_computerwinner.png  gem7.png                    princess.png
4row_humanwinner.png     gemgem.py                   RedSelector.png
gem1.png                 match5.wav                  Wall_Block_Tall.png
gem2.png                 memorypuzzle_obfuscated.py  Wood_Block_Tall.png
gem3.png                 memorypuzzle.py             wormy.py
Putting it all together

And as our final example we can combine our command (ls) with both an option (-l) and an argument (python_games) as follows;

Hopefully by this stage, the output shouldn’t come as too much surprise, although again I have pruned some of the files for readabilities sake;

pi@raspberrypi ~ $ ls -l  python_games
total 1800
-rw-rw-r-- 1 pi pi   9731 Jan 27 08:34 4row_arrow.png
-rw-rw-r-- 1 pi pi   7463 Jan 27 08:34 4row_black.png
-rw-rw-r-- 1 pi pi   8666 Jan 27 08:34 4row_board.png
-rw-rw-r-- 1 pi pi  18933 Jan 27 08:34 4row_computerwinner.png
-rw-rw-r-- 1 pi pi  25412 Jan 27 08:34 4row_humanwinner.png
-rw-rw-r-- 1 pi pi   8562 Jan 27 08:34 4row_red.png
-rw-rw-r-- 1 pi pi  14661 Jan 27 08:34 tetrisc.mid
-rw-rw-r-- 1 pi pi  15759 Jan 27 08:34 tetrominoforidiots.py
-rw-rw-r-- 1 pi pi  18679 Jan 27 08:34 tetromino.py
-rw-rw-r-- 1 pi pi   9771 Jan 27 08:34 Tree_Short.png
-rw-rw-r-- 1 pi pi  11546 Jan 27 08:34 Tree_Tall.png
-rw-rw-r-- 1 pi pi  10378 Jan 27 08:34 Tree_Ugly.png
-rw-rw-r-- 1 pi pi   8443 Jan 27 08:34 Wall_Block_Tall.png
-rw-rw-r-- 1 pi pi   6011 Jan 27 08:34 Wood_Block_Tall.png
-rw-rw-r-- 1 pi pi   8118 Jan 27 08:34 wormy.py

apt-get

The apt-get command is a program, that is used with Debian based Linux distributions to install, remove or upgrade software packages. It’s a vital tool for installing and managing software and should be used on a regular basis to ensure that software is up to date and security patching requirements are met.

There are a plethora of uses for apt-get, but we will consider the basics that will allow us to get by. These will include;

  • Updating the database of available applications (apt-get update)
  • Upgrading the applications on the system (apt-get upgrade)
  • Installing an application (apt-get install *package-name*)
  • Un-installing an application (apt-get remove *package-name*)
The apt-get command

The apt part of apt-get stands for ‘advanced packaging tool’. The program is a process for managing software packages installed on Linux machines, or more specifically Debian based Linux machines (Since those based on ‘redhat’ typically use their rpm (red hat package management (or more lately the recursively named ‘rpm package management’) system). As Raspbian is based on Debian, so the examples we will be using are based on apt-get.

APT simplifies the process of managing software on Unix-like computer systems by automating the retrieval, configuration and installation of software packages. This was historically a process best described as ‘dependency hell’ where the requirements for different packages could mean a manual installation of a simple software application could lead a user into a sink-hole of despair.

In common apt-get usage we will be prefixing the command with sudo to give ourselves the appropriate permissions;

apt-get update

This will resynchronize our local list of packages files, updating information about new and recently changed packages. If an apt-get upgrade (see below) is planned, an apt-get update should always be performed first.

Once the command is executed, the computer will delve into the internet to source the lists of current packages and download them so that we will see a list of software sources similar to the following appear;

pi@raspberrypi ~ $ sudo apt-get update
Hit http://raspberrypi.collabora.com wheezy Release.gpg
Get:1 http://mirrordirector.raspbian.org wheezy Release.gpg [490 B]
Get:2 http://archive.raspberrypi.org wheezy Release.gpg [473 B]
Hit http://raspberrypi.collabora.com wheezy Release
Get:3 http://mirrordirector.raspbian.org wheezy Release [14.4 kB]
Get:4 http://archive.raspberrypi.org wheezy Release [17.6 kB]
Hit http://raspberrypi.collabora.com wheezy/rpi armhf Packages
Get:5 http://mirrordirector.raspbian.org wheezy/main armhf Packages [6,904 kB]
Get:6 http://archive.raspberrypi.org wheezy/main armhf Packages [130 kB]
Ign http://raspberrypi.collabora.com wheezy/rpi Translation-en
Ign http://mirrordirector.raspbian.org wheezy/contrib Translation-en
Ign http://mirrordirector.raspbian.org wheezy/main Translation-en
Ign http://mirrordirector.raspbian.org wheezy/non-free Translation-en
Ign http://mirrordirector.raspbian.org wheezy/rpi Translation-en
Fetched 7,140 kB in 35s (200 kB/s)
Reading package lists... Done
apt-get upgrade

The apt-get upgrade command will install the newest versions of all packages currently installed on the system. If a package is currently installed and a new version is available, it will be retrieved and upgraded. Any new versions of current packages that cannot be upgraded without changing the install status of another package will be left as they are.

As mentioned above, an apt-get update should always be performed first so that apt-get upgrade knows which new versions of packages are available.

Once the command is executed, the computer will consider its installed applications against the databases list of the most up to date packages and it will prompt us with a message that will let us know how many packages are available for upgrade, how much data will need to be downloaded and what impact this will have on our local storage. At this point we get to decide whether or not we want to continue;

pi@raspberrypi ~ $ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be upgraded:
  bind9-host cups-bsd cups-client cups-common libapache2-mod-php5 libbind9-80 
  libisccc80 libisccfg82 liblwres80 libsdl1.2debian libsqlite3-0 libssl1.0.0 
  php5-mcrypt php5-mysql raspi-config
6 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 10.7 MB of archives.
After this operation, 556 kB disk space will be freed.
Do you want to continue [Y/n]?

Once we say yes (‘Y’) the upgrade kicks off and we will see a list of the packages as they are downloaded unpacked and installed (what follows is an edited example);

Do you want to continue [Y/n]? y
Get:1 http://archive.raspberrypi.org/debian/wheezy/main libsdl1.2debian
armhf 1.2.15-5+rpi1 [205 kB]
Get:2 http://archive.raspberrypi.org/debian/wheezy/main raspi-config all
20150131-5 [13.3 kB]
Get:3 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libsqlite3-0
armhf 3.7.13-1+deb7u2 [414 kB]
Fetched 10.7 MB in 31s (343 kB/s)
Preconfiguring packages ...
(Reading database ... 80703 files and directories currently installed.)
Preparing to replace cups-common 1.5.3-5+deb7u5 
(using .../cups-common_1.5.3-5+deb7u6_all.deb) ...
Unpacking replacement cups-common ...
Preparing to replace cups-bsd 1.5.3-5+deb7u5 
(using .../cups-bsd_1.5.3-5+deb7u6_armhf.deb) ...
Unpacking replacement cups-bsd ...
Preparing to replace php5-gd 5.4.39-0+deb7u2 
(using .../php5-gd_5.4.41-0+deb7u1_armhf.deb) ...
Unpacking replacement php5-gd ...
Processing triggers for man-db ...
Setting up libssl1.0.0:armhf (1.0.1e-2+rvt+deb7u17) ...
Setting up libsqlite3-0:armhf (3.7.13-1+deb7u2) ...
Setting up cups-common (1.5.3-5+deb7u6) ...
Setting up cups-client (1.5.3-5+deb7u6) ...

There can often be alerts as the process identifies different issues that it thinks the system might strike (different aliases, runtime levels or missing fully qualified domain names). This is not necessarily a sign of problems so much as an indication that the process had to take certain configurations into account when upgrading and these are worth noting. Whenever there is any doubt about what has occurred, Google will be your friend :-).

apt-get install

The apt-get install command installs or upgrades one (or more) packages. All additional (dependency) packages required will also be retrieved and installed.

If we want to install multiple packages we can simply list each package separated by a space after the command as follows;

apt-get remove

The apt-get remove command removes one (or more) packages.

cat

The cat command is a really versatile command that is typically used to carry out three different functions. It can display a file on the screen, combine different files together (concatenate them) or create new files. This is another core command that is immensely useful to learn in when working with Linux from the command line. It’s simple, flexible and versatile.

  • cat [options] filename filename : Display, combine or create new files.

For example: To display the file foo.txt on the screen we would use;

To display the files foo.txt and bar.txt on the screen one after the other we would use;

Or to combine the files foo.txt and bar.txt into a new file called foobar.txt using the redirection symbol >;

The cat command

The cat command is a vital tool to use on the Linux command line because ultimately Linux is an operating system that is file driven. Without a graphical user interface there needs to be a mechanism whereby creating and manipulating text files can be accomplished easily. The cat command is one of the commands that makes this possible. The name ‘cat’ is short for ‘catenate’ or ‘concatenate’ (either appears to be acceptable, but ‘concatenate’ appears to be more widely used), which is to say to connect things in a series. This is certainly one of it’s common uses, but a better overview would be to say that the cat command is used to;

  • Display text files at the command line
  • Join one text file to the end of another text file, combining them
  • Copy text files into a new document
Options

The only option that gets any degree of use with cat is the -n option that numbers the output lines.

Arguments and Examples

To display text

For example, to display a text file (foo.txt) on the screen we can use the following command;

The output would be;

pi@raspberrypi ~ $ cat foo.txt
This line is the contents of foo.txt

As we can see, the contents of the file ‘foo.txt’ is sent to the screen (be aware, if the file is sufficiently large, it will simple dump the contents in a long scrolling waterfall of text).

To join more than one file together

We could just as easily display two files one after the other (concatenated) as follows;

The output would be;

pi@raspberrypi ~ $ cat foo.txt bar.txt
This line is the contents of foo.txt
This line is the contents of bar.txt

To create a new file

Instead of having the file sent to the screen, we can specify that cat send our file to a new (renamed) file as follows;

This could be thought of an a equivalent to a file copy action and uses the redirection symbol >.

Taking the process one step further we can take our original two files and combine them into a single file with;

We can then check the results of our combination using cat on the new file as follows;

And the output would be;

pi@raspberrypi ~ $ cat foobar.txt
This line is the contents of foo.txt
This line is the contents of bar.txt

Then we could use cat to append a file to an already existing file by using the redirection operator >>;

Here we use the redirection operator >> to add the contents of the file newfoo.txt to the already existing file foobar.txt.

The resulting file content would be;

pi@raspberrypi ~ $ cat foobar.txt
This line is the contents of foo.txt
This line is the contents of bar.txt
And this is newfoo.txt

Finally, we can use cat to create a file from scratch. In this scenario if we use cat without a source file and redirect to a new file (here called newfile.txt. It will take the input from the command line to add to the file until CONTROL-d is pressed.

The resulting file content would be;

pi@raspberrypi ~ $ cat newfile.txt
Just keep typing
and entering information until...
we press ctrl-d to finish and the file gets written!
Test yourself
  1. Which is the safest redirector to use?
  2. Create a new file using cat and enter a few lines of text to give it some content
  3. Copy that file using cat to a new file.
  4. Combine the original file and the copy into a new file.
  5. Display that new file on the screen.

cd

The cd command is used to move around in the directory structure of the file system (change directory). It is one of the fundamental commands for navigating the Linux directory structure.

cd [options] directory : Used to change the current directory.

For example, when we first log into the Raspberry Pi as the ‘pi’ user we will find ourselves in the /home/pi directory. If we wanted to change into the /home directory (go up a level) we could use the command;

Take some time to get familiar with the concept of moving around the directory structure from the command line as it is an important skill to establish early in Linux.

The cd command

The cd command will be one of the first commands that someone starting with Linux will use. It is used to move around in the directory structure of the file system (hence cd = change directory). It only has two options and these are seldom used. The arguments consist of pointing to the directory that we want to go to and these can be absolute or relative paths.

The cd command can be used without options or arguments. In this case it returns us to our home directory as specified in the /etc/passwd file.

If we cd into any random directory (try cd /var) we can then run cd by itself;

… and in the case of a vanilla installation of Raspbian, we will change to the /home/pi directory;

pi@raspberrypi ~ $ cd /var
pi@raspberrypi /var $ cd
pi@raspberrypi ~ $ pwd
/home/pi

In the example above, we changed to /var and then ran the cd command by itself and then we ran the pwd command which showed us that the present working directory is /home/pi. This is the Raspbian default home directory for the pi user.

Options

As mentioned, there are only two options available to use with the cd command. This is -P which instructs cd to use the physical directory structure instead of following symbolic links and the -L option which forces symbolic links to be followed.

For those beginning Linux, there is little likelihood of using either of these two options in the immediate future and I suggest that you use your valuable memory to remember other Linux stuff.

Arguments

As mentioned earlier, the default argument (if none is included) is to return to the users home directory as specified in the /etc/passwd file.

When specifying a directory we can do this by absolute or relative addressing. So if we started in the /home/pi directory, we could go the /home directory by executing;

… or using relative addressing and we can use the .. symbols to designate the parent directory;

Once in the /home directory, we can change into the /home/pi/Desktop directory using relative addressing as follows;

We can also use the - argument to navigate to the previous directory we were in.

Examples

Change into the root (/) directory;

Test yourself
  1. Having just changed from the /home/pi directory to the /home directory, what are the five variations of using the cd command that will take the pi user to the /home/pi directory
  2. Starting in the /home/pi directory and using only relative addressing, use cd to change into the /var directory.

chmod

The chmod command allows us to set or modify a file’s permissions. Because Linux is built as a multi-user system there are typically multiple different users with differing permissions for which files they can read / write or execute. chmod allows us to limit access to authorised users to do things like editing web files while general users can only read the files.

  • chmod [options] mode files : Change access permissions of one or more files & directories

For example, the following command (which would most likely be prefixed with sudo) sets the permissions for the /var/www directory so that the user can read from, write to and change into the directory. Group owners can also read from, write to and change into the directory. All others can read from and change into the directory, but they cannot create or delete a file within it;

This might allow normal users to browse web pages on a server, but prevent them from editing those pages (which is probably a good thing).

The chmod command

The chmod command allows us to change the permissions for which user is allowed to do what (read, write or execute) to files and directories. It does this by changing the ‘mode’ (hence chmod = change file mode) of the file where we can make the assumption that ‘mode’ = permissions.

Every file on the computer has an associated set of permissions. Permissions tell the operating system what can be done with that file and by whom. There are three things you can (or can’t) do with a given file:

  • read it,
  • write (modify) it and
  • execute it.

Linux permissions specify what the owning user can do, what the members of the owning group can do and what other users can do with the file. For any given user, we need three bits to specify access permissions: the first to denote read (r) access, the second to denote (w) access and the third to denote execute (x) access.

We also have three levels of ownership: ‘user’, ‘group’ and ‘others’ so we need a triplet (three sets of three) for each, resulting in nine bits.

The following diagram shows how this grouping of permissions can be represented on a Linux system where the user, group and others had full read, write and execute permissions;

Linux permissions as rwx
Linux permissions as rwx

If we had a file with more complex permissions where the user could read, write and execute, the group could read and write, but all other users could only read it would look as follows;

Slightly more complex Linux permissions
Slightly more complex Linux permissions

This description of permissions is workable, but we will need to be aware that the permissions are also represented as 3 bit values (where each bit is a ‘1’ or a ‘0’ (where a ‘1’ is yes you can, or ‘0’ is no you can’t)) or as the equivalent octal value.

Linux permissions as symbolic, 3 bit and octal
Linux permissions as symbolic, 3 bit and octal

The full range of possible values for these permission combinations is as follows;

Permission              Symbolic 3-bit Octal
read, write and execute rwx      111   7
read and write          rw-      110   6
read and execute        r-w      101   5
read only               r--      100   4
write and execute       -wx      011   3
write only              -w-      010   2
execute only            --x      001   1
none                    ---      000   0

Another interesting thing to note is that permissions take a different slant for directories.

  • read determines if a user can view the directory’s contents, i.e. execute ls in it.
  • write determines if a user can create new files or delete file in the directory. (Note here that this essentially means that a user with write access to a directory can delete files in the directory even if he/she doesn’t have write permissions for the file! So be careful.)
  • execute determines if the user can cd into the directory.

We can check the check the permissions of files using the ls -l command which will list files in a long format as follows;

This command will list the details of the file foo.txt that is in the /tmp directory as follows

pi@raspberrypi ~ $ ls -l /tmp
-rwxrw-r-- 1 pi pi-group 20 Jul 10 13:14 foo.txt

The permissions on the file, the user and the group owner can be found as follows;

File details
File details

From this information we can see that the file’s user (‘pi’) has permissions to read, write and execute the file. The group owner (‘pi-group’) can read and write to the file and all other users can read the file.

Options

The main option that is worth remembering is the -R option that will Recursively apply permissions on the files in the specified directory and its sub-directories.

The following command will change the permissions for all the files in the /srv/foo directory and in all the directories that are under it;

Arguments

Simplistically (in other words it can be more complicated, but we’re simplifying it) there are two main ways that chmod is used. In either symbolic mode where the permissions are changed using symbols associated with read, write and execute as well as symbols for the user (u), the group owner (g), others (o) and all users (a). Or in numeric mode where we use the octal values for permission combinations.

Symbolic Mode

In symbolic mode we can change the permissions of a file with the following syntax:

  • chmod [who][op][permissions] filename

Where who can be the user (u), the group owner (g) and / or others (o). The operator (op) is either + to add a permission, - to remove a permission or = to explicitly set permissions. The permissions themselves are either readable (r), writeable (w), or executable (x).

For example the following command adds executable permissions (x) to the user (u) for the file /tmp/foo.txt;

This command removes writing (w) and executing (x) permissions from the group owner (g) and all others (o) for the same file;

Note that removing the execute permission from a directory will prevent you from being able to list its contents (although root will override this). If you accidentally remove the execute permission from a directory, you can use the +X argument to instruct chmod to only apply the execute permission to directories.

Numeric Mode

In numeric mode we can explicitly state the permissions using the octal values, so this form of the command is fairly common.

For example, the following command will change the permissions on the file foo.txt so that the user can read, write and execute it, the group owner can read and write it and all others can read it;

Examples

To change the permissions in your home directory to remove reading and executing permissions from the group owner and all other users;

To make a script executable by the user;

Windows marks all files as executable by default. If you copy a file or directory from a Windows system (or even a Windows-formatted disk) to your Linux system, you should ideally strip the unnecessary execute permissions from all copied files unless you specifically need to retain it. Note of course we still need it on all //directories// so that we can access their contents! Here’s how we can achieve this in one command:

This instructs chmod to remove the execute permission for each file and directory, and then immediately set execute again if working on a directory.

crontab

The crontab command give the user the ability to schedule tasks to be run at a specific time or with a specific interval. If you want to move beyond using Linux from a graphical user interface, you will most likely want to schedule a task to run at a particular time or interval. Even just learning about it might give you ideas of what you might do.

  • crontab [-u user] [-l | -r | -e] : Schedule a task to run at a particular time or interval

For example, you could schedule a script to run every day to carry our a backup process in the middle of the night. or capture some data every hour to store in a database.

The crontab command

The command crontab is a concatenation of ‘cron table’ because it uses the job scheduler cron to execute tasks which are stored in a ‘table’ of sorts in the users crontab file. cron is named after ‘Khronos’, the Greek personification of time.

While each user who sets up a job to run using the crontab creates a crontab file, the file is not intended to be edited by hand. It is in different locations in different flavour of Linux distributions and the most reliable mechanism for editing it is by running the crontab -e command. Each user has their own crontab file and the root user can edit another users crontab file. This would be the situation where we would use the -u option, but honestly once we get to that stage it can probably be assumed that we know a fair bit about Linux.

There are only three main options that are used with crontab.

Options

The first option that we should examine is the -l option which allows us to list the crontab file;

Once run it will list the contents of the crontab file directly to the screen. The output will look something like;

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

*/10 * * * * /usr/bin/php /home/pi/scrape-books.php

Here we can see that the main part of the file (in fact everything except the final line) is comments that explain how to include an entry into the crontab file.

The entry in this case is specified to run every 10 minutes and when it does, it will run the PHP script scrape-books.php (we’ll explain how this is encoded later in the examples section).

If we want to remove the current crontab we can use the -r option. Probably not something that we would do an a regular basis, as it would be more likely to be editing the content rather than just removing it wholesale.

Lastly there is the option to edit the crontab file which is initiated using -e. This is the main option that would be used and the one we will cover in detail in the examples below.

Examples

As an example, consider that we wish to run a Python script every day at 6am. The following command will let us edit the crontab;

Once run it will open the crontab in the default editor on your system (most likely ‘vi’, ‘vim’ or ‘nano’). The file will look as follows;

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

As stated earlier, the default file obviously includes some explanation of how to format an entry in the crontab. In our case we wish to add in an entry that tells the script to start at 6 hours and 0 minutes each day. The crontab accepts six pieces of information that will allow that action to be performed. each of those pieces is separated by a space.

  1. A number (or range of numbers), m, that represents the minute of the hour (valid values 0-59);
  2. A number (or range of numbers), h, that represents the hour of the day (valid values 0-23);
  3. A number (or range of numbers), dom, that represents the day of the month (valid values 0-31);
  4. A number (or list, or range), or name (or list of names), mon, that represents the month of the year (valid values 1-12 or Jan-Dec);
  5. A number (or list, or range), or name (or list of names), dow, that represents the day of the week (valid values 0-6 or Sun-Sat); and
  6. command, which is the command to be run, exactly as it would appear on the command line.

The layout is therefore as follows;

Linux permissions as rwx
Linux permissions as rwx

Assuming that we want to run a Python script called ‘m_temp.py` which was in the ‘pi’ home directory the line that we would want to add would be as follows;

0 6 * * * /usr/bin/python /home/pi/m_temp.py

So at minute 0, hour 6, every day of the month (where the asterisk denotes ‘everything’), every month, every day of the week we run the command /usr/bin/python /home/pi/m_temp.py (which, if we were at the command line in the pi home directory we would run as python m_temp.py, but since we can’t guarantee where we will be when running the script, we are supplying the full path to the python command and the m_temp.py script.

If we wanted to run the command twice a day (6am and 6pm (1800hrs)) we can supply a comma separated value in the hours (h) field as follows;

0 6,18 * * * /usr/bin/python /home/pi/m_temp.py

If we wanted to run the command at 6am but only on weekdays (Monday through Friday) we can supply a range in the dow field as follows (remembering that 0 = Sunday);

0 6 * * 1-5 /usr/bin/python /home/pi/m_temp.py

If we want to run the same command every 2 hours we can use the */2 notation, so that our line in the crontab would look like the following;

0 */2 * * * /usr/bin/python /home/pi/m_temp.py

It’s important to note that we need to include the 0 at the start (instead of the *) so that it doesn’t run every minute every 2 hours (every minute in other words)

Test yourself
  1. How could you set up a schedule job in crontab that ran every second?
  2. Create a crontab line to run a command on the 20th of July every year at 2 minutes past midnight.

ifconfig

The ifconfig command can be used to view the configuration of, or to configure a network interface. Networking is a fundamental function of modern computers. ifconfig allows us to configure the network interfaces to allow that connection.

  • ifconfig [arguments] [interface]

or

  • ifconfig [arguments] interface [options]

Used with no ‘interface’ declared ifconfig will display information about all the operational network interfaces. For example running;

… produces something similar to the following on a simple Raspberry Pi.

eth0      Link encap:Ethernet  HWaddr 76:12:45:56:47:53
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

wlan0     Link encap:Ethernet  HWaddr 09:87:65:54:43:32
          inet addr:10.1.1.8  Bcast:10.1.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3978 errors:0 dropped:898 overruns:0 frame:0
          TX packets:347 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:859773 (839.6 KiB)  TX bytes:39625 (38.6 KiB)

The output above is broken into three sections; eth0, lo and wlan0.

  • eth0 is the first Ethernet interface and in our case represents the RJ45 network port on the Raspberry Pi (in this specific case on a B+ model). If we had more than one Ethernet interface, they would be named eth1, eth2, etc.
  • lo is the loopback interface. This is a special network interface that the system uses to communicate with itself. You can notice that it has the IP address 127.0.0.1 assigned to it. This is described as designating the ‘localhost’.
  • wlan0 is the name of the first wireless network interface on the computer. This reflects a wireless USB adapter (if installed). Any additional wireless interfaces would be named wlan1, wlan2, etc.
The ifconfig command

The ifconfig command is used to read and manage a servers network interface configuration (hence ifconfig = interface configuration).

We can use the ifconfig command to display the current network configuration information, set up an ip address, netmask or broadcast address on an network interface, create an alias for network interface, set up hardware addresses and enable or disable network interfaces.

To view the details of a specific interface we can specify that interface as an argument;

Which will produce something similar to the following;

eth0      Link encap:Ethernet  HWaddr b8:27:eb:2c:bc:62
          inet addr:10.1.1.8  Bcast:10.1.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:119833 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8279 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:8895891 (8.4 MiB)  TX bytes:879127 (858.5 KiB)

The configuration details being displayed above can be interpreted as follows;

  • Link encap:Ethernet - This tells us that the interface is an Ethernet related device.
  • HWaddr b8:27:eb:2c:bc:62 - This is the hardware address or Media Access Control (MAC) address which is unique to each Ethernet card. Kind of like a serial number.
  • inet addr:10.1.1.8 - indicates the interfaces IP address.
  • Bcast:10.1.1.255 - denotes the interfaces broadcast address
  • Mask:255.255.255.0 - is the network mask for that interface.
  • UP - Indicates that the kernel modules for the Ethernet interface have been loaded.
  • BROADCAST - Tells us that the Ethernet device supports broadcasting (used to obtain IP address via DHCP).
  • RUNNING - Lets us know that the interface is ready to accept data.
  • MULTICAST - Indicates that the Ethernet interface supports multicasting.
  • MTU:1500 - Short for for Maximum Transmission Unit is the size of each packet received by the Ethernet card.
  • Metric:1 - The value for the Metric of an interface decides the priority of the device (to designate which of more than one devices should be used for routing packets).
  • RX packets:119833 errors:0 dropped:0 overruns:0 frame:0 and TX packets:8279 errors:0 dropped:0 overruns:0 carrier:0 - Show the total number of packets received and transmitted with their respective errors, number of dropped packets and overruns respectively.
  • collisions:0 - Shows the number of packets which are colliding while traversing the network.
  • txqueuelen:1000 - Tells us the length of the transmit queue of the device.
  • RX bytes:8895891 (8.4 MiB) and TX bytes:879127 (858.5 KiB) - Indicates the total amount of data that has passed through the Ethernet interface in transmit and receive.
Options

The main option that would be used with ifconfig is -a which will will display all of the interfaces on the interfaces available (ones that are ‘up’ (active) and ‘down’ (shut down). The default use of the ifconfig command without any arguments or options will display only the active interfaces.

Arguments

We can disable an interface (turn it down) by specifying the interface name and using the suffix ‘down’ as follows;

Or we can make it active (bring it up) by specifying the interface name and using the suffix ‘up’ as follows;

To assign a IP address to a specific interface we can specify the interface name and use the IP address as the suffix;

To add a netmask to a a specific interface we can specify the interface name and use the netmask argument followed by the netmask value;

To assign an IP address and a netmask at the same time we can combine the arguments into the same command;

Test yourself
  1. List all the network interfaces on your server.
  2. Why might it be a bad idea to turn down a network interface while working on a server remotely?
  3. Display the information about a specific interface, turn it down, display the information about it again then turn it up. What differences do you see?

ls

The ls command lists the contents of a directory and can show the properties of those objects it lists. It is one of the fundamental commands for knowing what files are where and the properties of those files.

  • ls [options] directory : List the files in a particular directory

For example: If we execute the ls command with the -l option to show the properties of the listings in long format and with the argument /var so that it lists the content of the /var directory…

… we should see the following;

pi@raspberrypi ~ $ ls -l /var
total 102440
drwxr-xr-x  2 root     root          4096 Mar  7 06:25 backups
drwxr-xr-x 12 root     root          4096 Feb 20 08:33 cache
drwxr-xr-x 43 root     root          4096 Feb 20 08:33 lib
drwxrwsr-x  2 root     uucp          4096 Jan 11 00:02 local
lrwxrwxrwx  1 root     root             9 Feb 15 11:23 lock -> /run/lock
drwxr-xr-x 11 root     root          4096 Jul  7 06:25 log
drwxrwsr-x  2 root     mail          4096 Feb 15 11:23 mail
drwxr-xr-x  2 root     root          4096 Feb 15 11:23 opt
lrwxrwxrwx  1 root     root             4 Feb 15 11:23 run -> /run
drwxr-xr-x  4 root     root          4096 Feb 15 11:26 spool
-rw-------  1 root     root     104857600 Feb 16 14:03 swap
drwxrwxrwt  2 root     root          4096 Jan 11 00:02 tmp
drwxrwxr-x  2 www-data www-data      4096 Feb 20 08:21 www
The ls command

The ls command will be one of the first commands that someone starting with Linux will use. It is used to list the contents of a directory (hence ls = list). It has a large number of options for displaying listings and their properties in different ways. The arguments used are normally the name of the directory or file that we want to show the contents of.

By default the ls command will show the contents of the current directory that the user is in and just the names of the files that it sees in the directory. So if we execute the ls command on its own from the pi users home directory (where we would be after booting up the Raspberry Pi), this is the command we would use;

… and we should see the following;

pi@raspberrypi ~ $ ls
Desktop  python_games

This shows two directories (Desktop and python_games) that are in pi’s home directory, but there are no details about the directories themselves. To get more information we need to include some options.

Options

There are a very large number of options available to use with the ls command. For a full listing type man ls on the command line. Some of the most commonly used are;

  • -l gives us a long listing (as explained above)
  • -a shows us aLL the files in the directory, including hidden files
  • -s shows us the size of the files (in blocks, not bytes)
  • -h shows the size in “human readable format” (ie: 4K, 16M, 1G etc). (must be used in conjunction with the -s option).
  • -S sorts by file Size
  • -t sorts by modification time
  • -r reverses order while sorting

A useful combination of options could be a long listing (-l) that shows all (-a) the files with the file size being reported in human readable (-h) block size (-s).

… will produce something like the following;

pi@raspberrypi ~ $ ls -lash
total 84K
4.0K drwxr-xr-x 13 pi   pi   4.0K May  7 11:46 .
4.0K drwxr-xr-x  3 root root 4.0K May  7 10:20 ..
4.0K -rw-r--r--  1 pi   pi     69 May  7 11:46 .asoundrc
4.0K -rw-------  1 pi   pi    854 Jul  8 12:55 .bash_history
4.0K -rw-r--r--  1 pi   pi   3.2K May  7 10:20 .bashrc
4.0K drwxr-xr-x  4 pi   pi   4.0K May  7 11:46 .cache
4.0K drwxr-xr-x  7 pi   pi   4.0K May  7 11:46 .config
4.0K drwxr-xr-x  2 pi   pi   4.0K May  7 11:46 Desktop
4.0K drwxr-xr-x  2 pi   pi   4.0K May  7 11:46 .fontconfig
4.0K drwxr-xr-x  2 pi   pi   4.0K May  7 11:46 .gstreamer-0.10
4.0K drwx------  3 pi   pi   4.0K May  7 11:46 .local
4.0K -rw-r--r--  1 pi   pi    675 May  7 10:20 .profile
4.0K drwxrwxr-x  2 pi   pi   4.0K Jan 27 21:34 python_games
4.0K drwxr-xr-x  3 pi   pi   4.0K May  7 11:46 .themes
Arguments

The default argument (if none is included) is to list the contents of the directory that the user is currently in. Otherwise we can specify the directory to list. This might seem like a simple task, but there are a few tricks that can make using ls really versatile.

The simplest example of using a specific directory for an argument is to specify the location with the full address. For example, if we wanted to list the contents of the /var directory (and it doesn’t matter which directory we run this command from) we simply type;

… will produce the following;

pi@raspberrypi ~ $ ls /var
backups  cache  lib  local  lock  log  mail  opt  run  spool  swap  tmp  www

We can also use some of the relative addressing characters to shortcut our listing. We can list the home directory by using the tilde (ls ~) and the parent directory by using two full stops (ls ..).

The asterisk (*) can be used as a wildcard to list files with similar names. E.g. to list all the png file in a directory we can use ls *.png.

If we just want to know the details of a specific file we can use its name explicitly. For example if we wanted to know the details of the swap file in /var we would use the following command;

… which will produce the following;

pi@raspberrypi ~ $ ls -l /var/swap
-rw------- 1 root root 104857600 May  7 11:29 /var/swap
Examples

List all the configuration (.conf) files in the /etc directory;

… which will produce the following;

pi@raspberrypi ~ $ ls /etc/*.conf
/etc/adduser.conf          /etc/host.conf       /etc/ntp.conf
/etc/ca-certificates.conf  /etc/idmapd.conf     /etc/pam.conf
/etc/debconf.conf          /etc/insserv.conf    /etc/resolv.conf
/etc/deluser.conf          /etc/ld.so.conf      /etc/resolvconf.conf
/etc/dhcpcd.conf           /etc/libaudit.conf   /etc/rsyslog.conf
/etc/fuse.conf             /etc/logrotate.conf  /etc/sysctl.conf
/etc/gai.conf              /etc/mke2fs.conf     /etc/ts.conf
/etc/gssapi_mech.conf      /etc/nsswitch.conf   /etc/ucf.conf

ping

The ping command allows us to check the network connection between the local computer and a remote server. It does this by sending a request to the remote server to reply to a message (kind of like a read-request in email). This allows us to test network connectivity to the remote server and to see if the server is operating. The ping command is a simple and commonly used network troubleshooting tool.

  • ping [options] remote server : checks the connection to a remote server.

To check the connection to the server at CNN for example we can simple execute the following command (assuming that we have a connection to the internet);

Which will return something like the following;

PING cnn.com (157.166.226.25) 56(84) bytes of data.
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=1 ttl=111 time=265 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=2 ttl=111 time=257 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=3 ttl=111 time=257 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=4 ttl=111 time=258 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=5 ttl=111 time=257 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=6 ttl=111 time=257 ms
^C
--- cnn.com ping statistics ---
14 packets transmitted, 13 received, 7% packet loss, time 13016ms
rtt min/avg/max/mdev = 257.199/267.169/351.320/24.502 ms

The first thing to note is that by default the ping command will just keep running. When we want to stop it we need to press CTRL-c to get it to stop.

The information presented is extremely useful and tells us that www.cnn.com’s IP address is 157.166.226.25 and that the time taken for a ping send and return message took about 250 milliseconds.

The ping command

The ping command is a very simple network / connectivity checking tool that is one of the default ‘go-to’ commands for system administrators. You might be wondering about how the name has come about. It is reminiscent of the echo-location technique used by dolphins, whales and bats to send out a sound and to judge their surroundings by the returned echo. In the dramatised world of the submariner, a ping is the sound emitted by a submarine in the same way to judge the distance and direction to an object. It was illustrated to best effect in the book by Tom Clancy and the subsequent movie “The Hunt for Red October” where the submarine commander makes the request for “One Ping Only”.

One Ping Only
One Ping Only

It works by sending message called an ‘Echo Request’ to a specific network location (which we specify as part of the command). When (or if) the server receives the request it sends an ‘Echo Reply’ to the originator that includes the exact payload received in the request. The command will continue to send and (hopefully) receive these echoes until the command completes its requisit number of attempts or the command is stopped by the user (with a CTRL-c). Once complete, the command summarises the effort.

From the example used above we can see the output as follows;

PING cnn.com (157.166.226.25) 56(84) bytes of data.
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=1 ttl=111 time=265 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=2 ttl=111 time=257 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=3 ttl=111 time=257 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=4 ttl=111 time=258 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=5 ttl=111 time=257 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=6 ttl=111 time=257 ms
^C
--- cnn.com ping statistics ---
14 packets transmitted, 13 received, 7% packet loss, time 13016ms
rtt min/avg/max/mdev = 257.199/267.169/351.320/24.502 ms

We can see from the returned pings that the IP address of the server that is designated as ‘www.cnn.com’ is ‘157.166.226.25’ The resolution of the IP address would be made possible by DNS, but using a straight IP address is perfectly fine). The icmp_seq= column tells us the sequence of the returned replies and ttl indicates how many IP routers the packet can go through before being thrown away. The time provides the measured return trip of the request and reply.

The summary at completion tells us how many packets were sent and how many received back. This forms a percentage of lost packets which is established over the specified time. The final line provides a minimum, average maximum and standard deviation from the mean.

Options

There are a few different options for use, but the more useful are as follows;

  • -c only ping the connection a certain number (count) of times
  • -i change the time interval between pings

It’s really useful to have ping running continuously so that we can make changes to networking while watching the results, but it’s also useful to run the command for a limited amount of time. This is where the -c option comes in. This will simply restrict the number of pings that are sent out and will then cease and summarise the effort. This can be used as follows;

Which will return something like the following;

PING cnn.com (157.166.226.25) 56(84) bytes of data.
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=1 ttl=111 time=266 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=2 ttl=111 time=263 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=3 ttl=111 time=288 ms
64 bytes from www.cnn.com (157.166.226.25): icmp_seq=4 ttl=111 time=280 ms

--- cnn.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 263.283/274.586/288.637/10.386 ms

Sometimes it can be convenient to set our own time interval between pings. This can be accomplished with the -i option which will let us vary the repeat time. The default is 1 second, however the value cannot be set below 0.2 seconds without doing so as the superuser. Interestingly there is an option to flood the network with pings (flood mode) to test the network infrastructure. However, this would be something typically left to research carefully when you really need it.

Test yourself
  1. How does the ping command to a server name know how to return an IP address?
  2. What does ‘ttl’ stand for?

sudo

The sudo command allows a user to execute a command as the ‘superuser’ (or as another user). It is a vital tool for system administration and management.

  • sudo [options] [command] : Execute a command as the superuser

For example, if we want to update and upgrade our software packages, we will need to do so as the super user. All we need to do is prefix the command apt-get with sudo as follows;

One of the best illustrations of this is via the excellent cartoon work of the xkcd comic strip (Buy his stuff, it’s awesome!).

Sudo courtesy xkcd
Sudo courtesy xkcd
The sudo command

The sudo command is shorthand for ‘superuser do’.

When we use sudo an authorised user is determined by the contents of the file /etc/sudoers.

As an example of usage we should check out the file /etc/sudoers. If we use the cat command to list the file like so;

We get the following response;

pi@raspberrypi ~ $ cat /etc/sudoers
cat: /etc/sudoers: Permission denied

That’s correct, the ‘pi’ user does not have permissions to view the file

Let’s confirm that with ls;

Which will result in the following;

pi@raspberrypi ~ $ ls -l /etc/sudoers
-r--r----- 1 root root 696 May  7 10:39 /etc/sudoers

It would appear that only the root user can read the file!

So let’s use sudo to cat](#cat) the file as follows;

That will result in the following output;

pi@raspberrypi ~ $ sudo cat /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/s\
bin:/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
pi ALL=(ALL) NOPASSWD: ALL

There’s a lot of information in the file, but there, right at the bottom is the line that determines the privileges for the ‘pi’ user;

pi ALL=(ALL) NOPASSWD: ALL

We can break down what each section means;

pi

pi ALL=(ALL) NOPASSWD: ALL

The pi portion is the user that this particular rule will apply to.

ALL

pi ALL=(ALL) NOPASSWD: ALL

The first ALL portion tells us that the rule applies to all hosts.

ALL

pi ALL=(ALL) NOPASSWD: ALL

The second ALL tells us that the user ‘pi’ can run commands as all users and all groups.

NOPASSWD

pi ALL=(ALL) NOPASSWD: ALL

The NOPASSWD tells us that the user ‘pi’ won’t be asked for their password when executing a command with sudo.

All

pi ALL=(ALL) NOPASSWD: ALL`

The last ALL tells us that the rules on the line apply to all commands.

Under normal situations the use of sudo would require a user to be authorised and then enter their password. By default the Raspbian operating system has the ‘pi’ user configured in the /etc/sudoers file to avoid entering the password every time.

If your curious about what privileges (if any) a user has, we can execute sudo with the -l option to list them;

This will result in output that looks similar to the following;

pi@raspberrypi ~ $ sudo -l
Matching Defaults entries for pi on this host:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User pi may run the following commands on this host:
    (ALL : ALL) ALL
    (ALL) NOPASSWD: ALL
The ‘sudoers’ file

As mentioned above, the file that determines permissions for users is /etc/sudoers. DO NOT EDIT THIS BY HAND. Use the visudo command to edit. Of course you will be required to run the command using sudo;

sudo vs su

There is a degree of confusion about the roles of the sudo command vs the su command. While both can be used to gain root privileges, the su command actually switches the user to another user, while sudo only runs the specified command with different privileges. While there will be a degree of debate about their use, it is widely agreed that for simple on-off elevation, sudo is ideal.

Test yourself
  1. Write an entry for the sudoers file that provides sudo privileges to a user for only the cat command.
  2. Under what circumstances can you edit the sudoers file with a standard text editor.