We are going to setup a Raspberry Pi for use as a headless server. Once it is setup and put in the closet, our only access is through SSH. So we will look at initial configuration, how to write and modify programs, how to grab source code from GitHub, how to get and configure applications.

In order to keep your Raspberry Pi software up to date, make changes, or issue new commands you will need to use the command line. Knowing a few commands, or working off a cheat sheet is easy. We will explore some basic commands, and learn how to find other commands.

Setting up the Raspberry Pi

We will walk through the Raspberry Documentation at RASPBERRY PI DOCUMENTATION.

Configuring the Pi

Again, we will walk through the Raspberry Documentation at CONFIGURATION.

Linux overview

Before looking at specific commands and options, I thought we would take a look at the Linux system in general. Since we will be dealing with a generic Linux I will try not to get into details specific to the different distributions of Linux. Much of this section is based on Linux part of the raspberry pi documentation.

File System

The Linux file system is based on a standard called Filesystem Hierarchy Standard (FHS).

The Filesystem Hierarchy Standard (FHS) defines the main directories and their contents in Linux and other Unix-like computer operating systems. FHS

Most of the time we will be in the home folder of the user pi, /home/pi. When ever you login to a Linux/Unix system you will be moved to the home folder for that user. If you promote your user to root, using sudo -i, you will move to /root folder.

Specific Directories of interest

While we are discussing the file system structure there are some directories that are of more than passing interest.


This directory contains the files belonging to each user. Besides holding your configuration files, it can contain your own executable files.


This directory contain many of the system configuration files. If we are configuring a system wide option, it is likely to be here.


This director contains information files about many applications.


This directory is where to store system wide commands and configurations for application that are not part of the distribution.


This is where the web pages go. This is the root for the web browser.


Virtual filesystem documenting kernel and process status, mostly text files.

Basic Commands

So now we have a working system, using a monitor, keyboard and mouse. But when we go to a headless server we are going to remove the monitor, keyboard and mouse. Normally the way we connect to the raspberry pi is using the SSH command.

Since we setup this utility during the configuration we are going to use it to connect to the raspberry pi from a laptop. You should open a terminal on your laptop, or use I will assume the IP address of the raspberry pi is

ssh -l pi

pi@'s password:

When the prompt comes up enter the password for the pi user raspberry. Even thought it recomments changing the pass word we are going to ignore for this talk, but at home you should pick another password to keep your system safe.

Alternately you can connect using the application Putty:

putty session
putty session

Now that we have connected to the card lets examine it using the command line.

Lets start by determining which directory we are in using pwd.


What files and directories are contained in the home directory.

ls /home/pi
ls . # The dot is the current directory
ls ~

Now lets add a couple of options to see how that effects the results.

ls -axF --color .

So what do these additional options do:

-a, --all
          do not ignore entries starting with .

-x     list entries by lines instead of by columns

-F, --classify
          append indicator (one of */=>@|) to entries

          colorize  the output; WHEN can be 'always' (default if omitted),
          'auto', or 'never'; more info below

For a more detailed listing of the files and directories, add the -l for long listing like

ls -laib --color .

The additional options are:

-l     use a long listing format

-i, --inode
          print the index number of each file

-b, --escape
          print C-style escapes for nongraphic characters

What are the directory entries labeled . and ..?

The . is the current directory. It is often used with commands to specify the command in the current folder as opposed to the one found in the path.

The .. is the parent directory. It can be used to specify a file or directory in the parent directory.

The ~ (tilde) is used as a alternate for your home directory. So if I am in the directory /home/pi and I want to view the file .bashrc I can use any of the less command in any of the following variation:

less .bashrc
less /home/pi/.bashrc
less ~/.bashrc
less ./.bashrc

If I wanted to change directories to /home I could do any of the following:

cd /home
cd ..

If I wanted to create a empty file named “test1” I could use the command: touch test1. If I wanted to rename the file from “test1” to “test2” I could use the command mv test1 test2 .

The Shell

In the Linux world the command line process is called the shell. Linux has several available, although the most common one is bash (Born Again SH). This is an improved version of the original Bourne shell which was called “sh”. There are a number of others: csh, tcsh, ksh, zsh, and fish. For this discussion I will focus on the default shell bash.

A few of the features we will discuss are alias, command line completion, command line editing, environment, I/O redirection, bracket expansion, process management, and shell scripts. For a good explanation of bash see Bash (Unix shell)


In the shell is allows you to create custom commands and link them to names. For example suppose I wanted to take the command above

ls -axF --color

and give it the name lc. I would create an alias like this:

alias lc="/bin/ls -axF --color"

you can use the command alias by itself to see what is defined.

command line completion

One of the useful commands I find is command line completion. This is especially useful for directory navigation. I can type the first few letters of a directory, and if these are unique I press the tab key to fill in the rest. For example:

/bin/ls /usr/sh\<tab>/doc/usbu\<tab

This will be expanded to

/bin/ls /usr/share/doc/usbutils/

This can be very handy when going deep into a directory structure.

command line editing

The shell maintains a stack of the commands. So to recall the last command you can use the up arrow. You can use the ^a to jump to the beginning of a line, or ^e to go to the end. You can search previous commands using ^s. For a full list of the commands see GNU Readline.


The environment variable are used to pass parameters to the commands. For example when you use the command date it will use the environment variable $TZ to determine your time zone.

You can see all the environment variables with the command env. You can display a specific variable with echo like echo $TZ. You use the command export TZ=EST5EDT to define a new variable.

I/O redirection

The shell defines three variables which are used by all commands.

  • stdin Standard input, file descriptor 0

  • stdout Standard output, file descriptor 1

  • stderr Standard error, file descriptor 2

These can be used to tie commands together or to redirect one of these variables. The most common modifier is | the pipe. This takes standard output of one command and passes it to standard input of another command.

env | less

Takes the output of the env command and passes it to the input of the less (a pager). One interesting facit of the pipe command is that both commands are run at once and the output passed to the input of the second command. So if the second commands input buffer fills, the first command is paused until there is room in the buffer. Unlike windows where the first command must finish before the second command begins, both commands are run using a memory buffer.

echo 'alias lc="/bin/ls -axF --color"' >> ~/.bashrc

Directs the output of the echo to be appended to the ~/.bashrc file.

grep -i linux *.txt 2>&1 | tee -a grep.output.txt

This takes the standard error, 2, and adds it to standard output, 1, of grep. Then the combined output is sent to the input of tee which displays the result on the screen and appends it to the file grep.output.txt.

echo -n "The date today: " > Today.txt 2>Today.err
date >>Today.txt 2>>Today.err

The echo -n sends the string “The date today:” to a new file, or over writes an existing file Today.txt. The 2> writes any errors to Today.err. The date appends the date stamp to the file Today.txt. The 2>> appends any errors to Today.err.

Bracket Expansion

The shell can use brackets to expand file names or other variables. Here are a few examples to elaborate.

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
$ echo file{1..4}.txt
file1.txt file2.txt file3.txt file4.txt
$ echo {a..e}
a b c d e
$ echo {1..10..3}
1 4 7 10
$ echo {a..j..3}
a d g j
$ echo a{p,c,d,b}e
ape ace ade abe
$ echo {a,b,c}{d,e,f}
ad ae af bd be bf cd ce cf

Process Management

The shell allows multiple commands to be executed when separated by ; semicolon. The commands are executed sequentially with the shell waiting for the completion of each job.

command ; command

If you want to put a command in the background and allow the command prompt to return immediately use the & (ampersand).

command &

When a command is followed by the ampersand it is executed in the background. If the command is graphic it will start in the same desktop but return the command prompt to the shell. To view which commands are executing in the background use the command jobs. To stop a job executing in the background you can use the job number. These are for job 1.

kill -s SIGKILL %1
kill -9 %1

You can also use the conditional operator && which will not run the second command unless the first command is successful.

cd "$SOMEWHERE" && ./do_something || echo "An error occurred" >&2

When a command exits it returns status in the variable $?.

Shell Scripts

This is a subject of a whole talk, but for a quick introduction let me show you a command line script, then convert it to a shell script.

find tmp -type f -iname "*.txt" -print | while read FIL ; do echo \
"${FI:} ; grep -n -i "tai chi" "${FIL} ; done | less

This script uses the command find to search a directory tree of files for any file named .txt. It then passes the name to the variable FIL inside a while loop. The variable ${FIL} is then echoed to the command line before being parsed by grep* for the string “tai chi” case insensitive. Finally the output is passed to the pager less.

So a shell script for this replacing the file name and search string with input parameters might look like this:

# File: /home/pi/bin/search-string.sh
# Date: Mon 17 Dec 2018 19:02:11 EST

# Check for input parameters
if [ $1 -eq "" ] || [ $2 -eq "" ] || [ $3 -eq "" ]
    echo "Usage $0 Start-Directory File-Names Search-Value"
    exit 1

# Run search
/bin/find "${1}" -type f -iname "${2}" -print | \
while read FIL
    echo "${FIL}"
    grep -n -i "${3}" "${FIL}"
done | \

Useful Info

In the shell the **** (back quote) is used as an escape character. For example if I wanted to echo a sentence with a quote in it I would use.

echo "The file name is \"First Name Only.txt\" "

Anything following a # is considered a comment. This can be used in scripts or command lines.

echo "Today is Tuesday" # only useful on Tuesday.

Linux is Case Sensitive. So a two files named “john.txt” and “John.txt” are different files. The same thing is true for commands.

More to Follow

I decided to stop here because there is so much more to talk about in Linux. Let me give you a few topics we have not begun to cover yet.

  • System Start-up tasks

  • Scheduled tasks

  • Web pages

  • Control of GPIO pins on the Raspberry Pi

  • Programming languages

  • Updating the software

  • Installing programs not in the repositories

  • Text Editors

  • Permissions

  • Security

Written by John F. Moore

Last Revised: Mon Dec 17 20:01:41 EST 2018

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
HTML5 Powered with CSS3 / Styling, and Semantics