Defindit Docs and Howto Home

This page last modified: Dec 17 2010
keywords:intro,introduction,linux,tutorial,osx,macos,fedora,ubuntu,unix,command,bash,shell,line,command line,
description:Examples of common commands in Linux shells and how to use the command line.
title:Linux command line introduction and examples.

Table of contents
Introduction to Unix(TM) (Linux and Mac OSX(TM))
Navigating directories
Listing directory contents
Copying files
Moving and renaming files
Viewing files
Deleting files
Viewing and saving command output
Searching inside files

Introduction to Unix, Linux, and Mac OSX

Modern Linux (conceptually based on Unix) has a graphical desktop just like
Windows(TM) and MacOS. Linux even has some themes and skins that make
it look and work identical to Windows or Macintosh (the look and feel
is user configurable). Mac OSX is a Unix-variant (the Berkeley
Standard Distribution or BSD), and is therefore very similar to Linux
in most regards.

In spite of the graphical desktops, there are still many powerful
features only available at the command line. There are all kinds of
wonderful and useful tools. The command line is available via a
terminal application. Under Linux there are several choices. For many
years my favorite was Konsole that comes with the KDE desktop. Lately
I've switched over to an old classic called xterm. The Gnome desktop
has a terminal also. On the Mac you can use Terminal. If you use an
ssh terminal program such as PuTTY or SecureCRT, you will be logging
in and working in a command line shell on the Linux server.

We will start with an overview of how to enter rudimentary commands
and how to navigate at the command line. Then we'll move on to some
useful tricks.

In this document, the first time a new command or term is used, it
will appear surrounded by double quotes. For example, the command
line is also known as the "shell". We will assume you are using the
"bash" shell, which is the a modern shell, and is the default in
Linux and OSX.

The first thing you see is a "prompt" which is a string of characters
used by the computer to show that is it ready for a command. The
computer is waiting for you to type a command. All commands have at
least one word, and you must press the enter key to launch the
command. There is no harm in pressing the enter key without a command.
(In fact many experienced users hit the enter key a few times just to
assure themselves that the computer is listening.)

Different parts of the command are separated by spaces. Extra spaces
are usually ok. Some parts of some commands must occur in a specific

The "control key" is important in bash. Use it like the shift key. To
enter control-c, hold down control and press c. Sometimes control-c is
written ctrl-c or ^c or even occasionally (and incorrectly) in upper
case Control-C. Bash is almost universally lowercase, and it is case
sensitive. Do not use upper case characters unless there is a reason
(such as an uppercase character in a file name, or a command switch is
uppercase). Bash has all kinds of handy control characters that it
recognizes, but ^c is the most important.

If you type a command, but change your mind ^c will cancel. If a
command is running and hasn't completed (or is going wild) ^c will
stop the command (eventually). It is ok to type ^c several times. Bash
is stopped with the "exit" command or ^d (control-d).

The most common commands fall into broad categories. Your graphical
desktop has functions to do the same things as the most common bash
commands. The really interesting stuff you can do at the command line
is not possible with graphical desktops.

We will also use the command syntax description that you'll find in
"man pages". Anything in [] is optional. "Switches" are preceded by
one hyphen, and switches with long names have double hyphens. Switches
enable or disable extra features of the command. You must type the
hyphen/double hyphens as necessary. You must not have a space between
the hyphen and the text of the switch. When reading man pages, some of
the syntax used to describe a command is not literal text, but refers
to a variable. Anything variable (like a file name) will be explained
in the help for that command. It is sometimes tricky to determine what
is literal text and not. Examples should clarify this.

The broad categories are below. For historical reasons (and
consistency with other documentation) we call "folders" "directories".

* navigating directories
* listing directory contents
* copying files
* moving and renaming
* deleting
* running programs

After these fundamental commands, we'll explore powerful and useful
commands which give you features that aren't available from a
graphical desktop interface.

Navigating directories

This is done with one command "cd" (change directory). The format is:

cd [-L|-P] [dir]

Change directory to dir. There are some special directory names:
The directory immediately up (parent directory) is ..
The current directory is (dot) .

You can change several directories down or up by using a longer

cd public_html
Changes to the public_html directory.

cd public_html/images
Changes to the images directory in public_html.

cd ../../.ssh
Changes up two directories into a directory .ssh (yes, the name begins
with a dot).

Listing directory contents

ls [OPTION]... [FILE]...

ls (list sorted) has many options, and can take many files as arguments.

A plain listing of the current directory.

ls -l
Long listing of the current directory

ls -la
Long listing, and include "hidden" files with dot at the beginning of their name.

ls -l *
List everything and also list contents of directories in this directory.

ls public_html/images
List the files in the images directory in the public_html directory.

ls -l public_html/images/*.jpg
Only list .jpg files in the images directory.

ls -alt
List all the files, starting with newest.

For more exciting reading see man ls.

Copying files

cp [OPTION]... --target-directory=DIRECTORY SOURCE...

Copy a file from source to destination. Works also to copy a file into
a directory. cp is smart enough to know not to overwrite a directory
with a file (that's impossible anyway).

cp index.html

Copy our default home page index.html to It is ok to
have a file with two extensions, however, the web server won't know
that a .safe is really a .html file.

cp index.html ../

Copy index.html up a directory.

cp has funny behavior when copying directories. If you want the
directory and all the subdirectories copies, you have to use the -r

cp -r public_html backup_public_html

Moving and renaming files

mv [OPTION]... --target-directory=DIRECTORY SOURCE...

mv works similar to cp. However, mv will rename directories.

mv query.cgi

Rename (move) to query.cgi

mv /home/mst3k/

Move to the home directory of mst3k.

Unlike what you might expect, you can't use mv to change the extensions of files.

mv *.pl *.cgi

This won't work. In fact mv will give a message: "mv: when moving
multiple files, last argument must be a directory"

There is a "rename" utility for wild card renaming. Be careful with
rename since is can make a real mess. In fact, it is off topic, but
pertinent: before trying any command that may destroy files, it is
good to make a backup. The "tar" utility is good for this. Basic use
of tar required one command to build a tar archive, and a second
command to un-tar the archive. -c is create and -x is extract:

tar -cvf tmp.tar *.pl

Will create the tar archive tmp.tar from all the .pl files in this directory.

tar -xcf tmp.tar

will extract all the files in tmp.tar

tar -tvf tmp.txt 

will list all the files in the archive, but not change anything.

rename looks like this:
rename from to file...

"from" is a part of a file name, "to" is what you want the matching
part changed to, and "file..." is a file or list of files.

To use rename for the mv example above that doesn't work:

rename .pl .cgi *.pl

Viewing files

This is where the fun starts. Text files are viewed with "more" or
"less". Special files like images and word processing are viewed with
the usual image editors and word processors, so we won't cover those.

It turns out that "less" has more features than "more" which leads to
the geeky joke "less is more".

more [-dlfpcsu] [-num] [+/ pattern] [+ linenum] [file ...]
less -?
less --help
less -V
less --version
less [-[+]aBcCdeEfFgGiIJLmMnNqQrRsSuUVwWX~]
[-b space] [-h lines] [-j line] [-k keyfile]
[-{oO} logfile] [-p pattern] [-P prompt] [-t tag]
[-T tagsfile] [-x tab,...] [-y lines] [-[z] lines]
[-# shift] [+[+]cmd] [--] [filename]...

That's a lot of information. The usual case is just


Both will scroll the file onto the screen, stopping after each
screen. Press "space bar" for the next screen. Press "enter" to move
down one line. Press "q" to exit.

There is one difference between less and more: After it exits, the
text more displayed stays on the screen.

"less" has all kinds of additional abilities. You can use the cursor
keys and page-up/page-down with less. less can also search forward and
backward. To search forward, press / (forward slash, below the ?),
then enter some text and press enter. Press "n" to find that same text
again, and "b" to find previous. less is case sensitive. Enter "-i"
and press enter to switch less to case insensitive mode. If less
doesn't seem to be in command mode use ^c or ":" the colon. less will
not be killed by ^c, so you'll have to exit with q.

more only works on text files. less will display binary files, and in
my experience won't mess up your terminal settings (like might happen
with "cat" on a binary file).

You can also display files with the text editors vi (vim) and
emacs. Both of those utilities are complex enough to deserve their own
documentation. In modern version of both you can probably scroll
around with the arrow keys and page-up/page-down. Exit from emacs with
^x^c and exit from vi by entering command mode with Esc "escape" or
":" and quit with q.

Deleting files

Deleting files is dangerous in Linux and BSD because it's creators
have not seen fit to allow undelete or to implement a trash can. This
is just one of many cases of snobbery amongst Linux and BSD
people. They have all kinds of justifications, and they clearly aren't
about to change, so we'll have to work around the problem.

Perhaps the safest thing is to simply mv files to your favorite trash

mv ~/Desktop/Trash

move to Desktop/Trash in my home directory. ~/ is short hand for "my home directory".

When you want to get rid of a file, use rm.



Often the "rm" command has been aliased to "rm -i" which is
"interactive" which means it asks before doing anything. Answer with y
and enter to delete the file or n and enter (or just enter) to keep
the file.

[mst3k@tull ~]$ rm -i
rm: remove regular file `'? y
[mst3k@tull ~]$

The most dangerous command is "rm -fr *" which is rm force, recurse
all files. "force" is don't ask, "recurse" is go into all
subdirectories. This command can delete every file you own. If you are
logged in as root, you can delete ever file on the disk.

If you want to use rm -fr, follow these steps for safety (and maybe
make a tar file first). We'll clean up everything in the "mars"
directory. The commands below will: cd into mars, check that we really
are in the mars directory (pwd is "print working directory"), ls the
directory to make sure it really has the files we think it has, then
use a variation of rm -fr that deletes files starting in this
directory, and at last we ls and that everything is gone. ls -l might
have been a better command. You can't tell here, but "sol62_fr" and
"front_right" are both directories with files in them. All those files
were deleted.

[mst3k@tull ~]$ cd mars
[mst3k@tull mars]$
[mst3k@tull mars]$ pwd
[mst3k@tull mars]$ ls
2R131787621EFF1200P1310R0M1-BR.JPG 2R131962287EFF1400P1310R0M1-BR.JPG sol62_fr
2R131871671EFF1300P1310R0M1-BR.JPG front_right
[mst3k@tull mars]$ rm -fr ./*
[mst3k@tull mars]$ ls
[mst3k@tull mars]$

Running programs

By this point in the tutorial you have been running programs. Most
commands are simply programs. There are hundreds of them, but only a
few dozen are commonly used. If you try to run a command that does not
exist, you'll get an error message:

[mst3k@tull ~]$ argle
bash: argle: command not found
[mst3k@tull ~]$

If you run a command that fails, you will also get an error message:

[mst3k@tull ~]$ cd argle
bash: cd: argle: No such file or directory
[mst3k@tull ~]$

The bash shell has "tab completion" which is a wonderful feature. It
is so wonderful that people like myself can't imagine using a
graphical interface where tab complete doesn't exist. Press tab once
to complete a command, file name, or directory name. If the name does
not complete, press tab a second time to get a list of possible
completions. In the example below I'm looking for a ls command, but I
can't remember the name. I type "ls" then hit tab twice:

[mst3k@tull ~]$ ls
ls        lsbom     lsdistcc  lshal     lsm       lsof      lsvfs     
[mst3k@tull ~]$ ls

Tab complete is very handy for entering long directory paths and file
names. Type part, hit tab, type a little more, hit tab again. It
becomes easy to tab-complete to enter a path such as


It is an interactive process. Occasionally you'll get a message such as:

Display all 1086 possibilities? (y or n)

Displaying that can take several screens. The list will be sorted. You
might want to enter "n" and then enter one or two more letters before

[mst3k@tull ~]$ less /usr/bin/
Display all 1086 possibilities? (y or n) n
[mst3k@tull ~]$ less /usr/bin/p
Display all 137 possibilities? (y or n) n
[mst3k@tull ~]$ less /usr/bin/pr
pr           priclass.d   printenv     procmail     profiles     prove  prove5.8.9   
pre-grohtml  pridist.d    printf       procsystime  projectInfo  prove5.10.0  
[mst3k@tull ~]$ less /usr/bin/pr

Viewing and saving command output

If you want to ls -l a very large number of files, the list will
scroll off the screen. Shell commands can be "piped" together. The
output of one command is the input of another. In general this falls
into the categories of "piping output" and "i/o redirection" (sometimes
spelled "io") for input/output. Pipes use the pipe character "|" which
is shift "\" (backslash) on most keyboards, and above the enter key.

ls -l | less

A long list all files piped to less. Now you can scroll up and down
the list with less, and even search. You could send the list to a file
with i/o redirection.

ls -l > ls_out.txt
less ls_out.txt

Make a long listing, send it to the file ls_out.txt, then less the
file. Capturing output is very handy when it will take a long time to
run a command. For instance, getting a list of packages that yum can
install might take a minute or two. I prefer to save the listing to a
file and search the listing with less or grep.

yum list all > yum_list.txt

The > will take output and redirect it to a file. The file is
overwritten, which means that the contents of the file are
destroyed. There is no undo. You often want to overwrite temporary
files. However, if you have something like a log file, you probably
want to append output (concatenate). Use the >> redirection.

ls -alt ./documentation/* >> big_list.txt
ls -alt ./spreadsheets/* >> big_list.txt

Make a date sorted long list of all files, and append it to the end of

In the example below we overwrite big_list.txt with > and then append with >>

ls -alt ./new_files/* > big_list.txt
ls -alt /home/mst3k/* >> big_list.txt

Searching inside files

The utility "grep" (get regular expression and print) will search for
regular expression matches inside files. grep has many uses, and we'll
only cover a few more common examples.

Regular expressions are a way of describing simple or complex wild
card text matches. However, the regex * is not a wild card. Instead
"." (dot) matches any single character. Perhaps the best way to use
grep (at least on Linux) is to rely on simple regex's and if you need
something complex, use the Perl regex switch "-P" and read Perl's
perlre man page "man perlre". I don't think BSD is using the GNU grep,
so they probably don't have Perl regex's available.

grep tcp /etc/services

Will search /etc/services for "tcp", and print every line that matches.

ls /etc/ | grep serv

Will list all the files in /etc, pipe the list to grep, and grep will
search that list for matches to "serv".

The output of grep can be long. You can find out which files contain
some text, but you'll have to pipe the list through less

grep tcp /etc/s* | less

Will grep /etc/s* (which is a lot of files) looking for "tcp". Some
files you can't read, and so a few permission messages will
print. That's ok.

Use the -c to get a count of matches in each file.

grep -c tcp /etc/s* | less
This prints lines like

We really are only interested in files that don't have zero matches,
so we can use the -v switch to get lines which did not match (reversed

grep -c tcp /etc/s* | grep -v :0

Search for matches against "tcp" and pipe that list to grep and search
for lines that did not match ":0". Below is a transcript.

[mst3k@tull ~]$ grep -c tcp /etc/s* | grep -v :0
grep: /etc/securetty: Permission denied
grep: /etc/shadow: Permission denied
grep: /etc/shadow-: Permission denied
grep: /etc/sudoers: Permission denied
[mst3k@tull ~]$

It is common to use grep, ls as well as "wc" and "find". find is
complicated and deserves its own chapter. wc is "word count" is will
count bytes, words, and lines.

ls *.pl | wc -l

List all the Perl scripts and count them (by counting the lines in the

Here is an example using the Perl extended regexps in grep. The regexp
"\d+" means "match digits where there is at least 1 digit".

ls | grep -P "\d+" | less

There are a few oddities at the command line. It can be tricky to list
files with a leading dot (called "dot files") without listing other
files. Deleting dot files require a trick or two. Dealing with files
that have strange characters (including spaces) in the file names also
requires special tricks. "Quoting" also known as "escaping" can be
helpful. The command below escapes a space so that I can list all
files that have a space in the name. Interestingly, the file is a
symbolic link to a longer file name in another directory.

[mst3k@tull ~]$ ls -l *\ *
lrwxr-xr-x  1 mst3k mst3k  65 Apr  2 10:17 Archivists' Toolkit 2.0 -> /Applications/Archivists' Toolkit 2.0/Archivists' Toolkit
[mst3k@tull ~]$