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.
We will walk through the Raspberry Documentation at RASPBERRY PI DOCUMENTATION.
Again, we will walk through the Raspberry Documentation at CONFIGURATION.
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.
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.
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.
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 192.168.1.137.
ssh -l pi 192.168.1.137
pi@192.168.1.137'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:
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.
/home/pi
What files and directories are contained in the home directory.
ls /home/pi
ls
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
--color[=WHEN]
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 .
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.
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.
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.
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.
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
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 $?.
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:
#!/bin/bash
# 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 "" ]
then
echo "Usage $0 Start-Directory File-Names Search-Value"
exit 1
fi
# Run search
/bin/find "${1}" -type f -iname "${2}" -print | \
while read FIL
do
echo "${FIL}"
grep -n -i "${3}" "${FIL}"
done | \
less
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.
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