If geeks love it, we’re on it

Ultimate Newbie Guide to the GNU/Linux Shell

Ultimate Newbie Guide to the GNU/Linux Shell

Why you should consider it: You should learn your GNU/Linux commands even if you’re using a GUI so you have better control over your system.

Ultimate Newbie Guide to the GNU/Linux Shell

by drasnor

This primer aims to demystify usage of common shells used with the GNU/Linux operating system. Interaction with the shell, also known as the command prompt or command line, has been historically a major factor in the reluctance of Windows users to use GNU/Linux. However, with a proper understanding of the shell both your GNU/Linux experience and your Windows experience will improve since the Windows NT shell and DOS are both quite similar to the GNU/Linux shell.

A note for advanced users checking my work: this primer was written for the bash shell since it is the most common shell in use today. However, the lessons covered here are so basic that they ought to apply to the other shells as well. Feel free to note any differences in the comments section.

What if I mess something up?

Fortunately for you, GNU/Linux makes a distinction between ordinary users and the super user. All commands that can mess up your computer must be run by the super user or root user to take effect. As long as you’re logged in as your normal user account, you can’t do any harm to anything except whatever files you have in your personal directory.

It is bad practice to log in as the super user (root) all the time. Sure it can be convenient but at the same time you create a major security hole in your system. As root all processes (applications, services, etc.) you initiate are run in privileged mode so if you happen to browse a malicious website that can attack GNU/Linux PCs, any processes it initiates run on the system in privileged mode and can do anything they like. By logging in as a normal user, any processes you initiate run in protected mode and malicious websites can’t go willy-nilly installing spyware, viruses, or trojans on your PC.

Do Not Practice Shell As root. You Have Been Warned.


Listing Directory Contents

The first thing you see when you fire up your favorite terminal is your prompt. On my PC, this looks like:

drasnor@jormungand ~ $

The first part is your username (I’m drasnor!), @jormungand since I’m logged in on my computer whose hostname is jormungand. ~ is the current directory, and $ indicates my current user mode. If you see a # here instead of a $, you’re logged in as root and should probably log out and log in as a normal user. ~ always refers to your home directory. More on this later.

The first and probably most frequently-used shell command is ls which displays the content of the current working directory like so:

drasnor@jormungand ~ $ ls
drasnor@jormungand ~ $

Depending on how your shell is configured, files and directories may be colored differently so you can tell them apart at a glance. If they’re not, that’s alright because ls can also tell us this with the -l option:

drasnor@jormungand ~ $ ls -l
total 169643
drwxr-xr-x 3 drasnor users 80 Feb 21 15:56 Desktop
drwxr-xr-x 14 drasnor users 552 Jan 26 15:56 Music
drwxr-xr-x 5 drasnor users 8512 Feb 21 23:27 Pictures
drwxr-xr-x 8 drasnor users 192 Aug 1 1999 ground0
-rw-r–r– 1 drasnor users 160307 Feb 15 14:34 ground0.tgz
drasnor@jormungand ~ $

Let’s take a moment to understand what ls is telling us. From left to right, the string of characters includes information on the file type and permissions set on the file, the next number is the number of hard links to the file (a filesystem trait beyond the scope of this primer), followed by the file’s owner (me), then the owning group (users), the file size in bytes, the date of most recent modification, and finally the file’s name.

Let’s take a look at that first string of characters. The first character in the string denotes the file type; d is for directories and is for normal files. The next nine characters are arranged in triplets of three characters each. The first triplet denotes what permissions the file’s owner has, the second triplet denotes what other members of the owning group can do, and the last triplet denotes what other non-group members can do. The first character of each triplet denotes the read privileges of the file ( for unreadable, r for readable), the second character denotes the write privileges ( for write-protected, w for writable), and the third character denotes the execute privileges ( for non-executable, x for executable). For example, the file

-rw-r–r– 1 drasnor users 160307 Feb 15 14:34 ground0.tgz

is a normal file that I (the owner) can read and write but not execute and others can only read. If all this seems confusing don’t worry about it since most files are created with the correct permissions for whatever they are.

All GNU/Linux distributions store user information in hidden files and directories in your home folder. You can see these files and directories using ls -a:

drasnor@jormungand ~ $ ls -a

This is particularly useful because if you need to edit the configuration of some of your programs by hand or migrate your e-mail and bookmarks to a new computer you’ll need to access these hidden files and directories.

Changing Directories

Though browsing our home directory has been fun, you might want to check out the contents of another directory. This is done using cd:

drasnor@jormungand ~ $ cd ground0
drasnor@jormungand ~/ground0 $

Note that our prompt has changed to reflect the new working directory. ls works here too:

drasnor@jormungand ~/ground0 $ ls
boot doc gods log player src
drasnor@jormungand ~/ground0 $

Also note that ls tends to use the most convenient output format it can. You probably noticed that there are two files in my home directory named . and ..; these files are actually links to the current directory and the parent directory respectively. This means that cd . won’t really do anything since you’re telling the shell to change to the current directory. However, you can get back to where you started using cd ..

drasnor@jormungand ~/ground0 $ cd ..
drasnor@jormungand ~ $

Creating Directories

Let’s try our hand at making directories. GNU/Linux uses the command mkdir to do this:

drasnor@jormungand ~ $ mkdir Video
drasnor@jormungand ~ $ cd Video
drasnor@jormungand ~/Video $ ls -a
. ..
drasnor@jormungand ~/Video $ cd ..
drasnor@jormungand ~ $

Notice how I spelled Video with a capital V? Here’s the reason:

drasnor@jormungand ~ $ cd video
bash: cd: video: No such file or directory
drasnor@jormungand ~ $

GNU/Linux is case-sensitive unlike Windows and DOS. This means that you can have a file or directory named Video which is distinct and separate from video as well as from ViDeO and so on.

Copying and Moving Files

Creating a duplicate of file A in directory A has never been easier. This task is accomplished using cp:

drasnor@jormungand ~ $ cp ground0.tgz ground0.bak
drasnor@jormungand ~ $

The first file listed is the original filename and the second is the new filename. Now I want file A moved to directory B. GNU/Linux provides mv for this purpose:

drasnor@jormungand ~ $ mv ground0.bak ~/Video/
drasnor@jormungand ~ $

The first part is the name of the file to be moved and the second part is the path to the directory where I want the file to go. Since I’m already in ~ (see the prompt if you weren’t sure), I could’ve just as easily sent the file to Video/ and had the same effect. Of course, if I weren’t in ~ and wanted to move the file to Video/, ~/Video/ will always get me there since ~ is defined as a special folder in GNU/Linux.

Removing Files and Directories

Empty directories are removed using rmdir. rmdir will not operate on directories with files in them by nature:

drasnor@jormungand ~ $ rmdir Video
rmdir: `Video’: Directory not empty
drasnor@jormungand ~ $

This is because of how rmdir operates and not due to the system trying to prevent you from hurting things. In order to use rmdir first you must remove any files in the directory using rm:

drasnor@jormungand ~ $ rm Video/*
drasnor@jormungand ~ $

* is a wildcard, a special character that GNU/Linux that cannot be used in a filename because it has a special meaning. * literally means everything so the result of the above command is removing everything. Be careful how you use * and rm together because you can delete all of your files with it if you aren’t careful. From here, rmdir should work as advertised:

drasnor@jormungand ~ $ rmdir Video/
drasnor@jormungand ~ $

If you wanted to clean out Video/ and remove it all in one swoop, rm has an option that can do this for you:

drasnor@jormungand ~ $ rm -r Video/
drasnor@jormungand ~ $

If you were logged in as root and were in the lowest level of your computer’s filesystem, the command rm -r * is functionally identical to formatting your hard drive! Luckily, as a normal user GNU/Linux will not allow you to destroy anything besides your own files. You’ll get a message along the lines of:

rm: cannot remove `blah’: Permission denied

Don’t try it though.

Useful System Commands:

Tab Completion

GNU/Linux can start guessing what you’re typing anytime you don’t feel like typing out a full filename. Simply hitting tab after typing a few characters tells GNU/Linux to type out the rest of the filename up to where it is different from another file. For instance, if I have two files ground0.tgz and ground1.tgz, typing ‘g‘ and hitting tab would fill in up to ‘ground‘. I would then have to type either ‘0‘ or ‘1‘ and hit tab again before GNU/Linux can guess the rest.

Command History:

Pressing the up arrow key will cycle through the history of every command typed on the terminal you’ve been using. This is useful for if you need to repeat a command you typed earlier or made a typo and don’t want to type the whole command again. If you go back too far just press down arrow to scroll back.

echo – Can You Hear Me Now?

echo is a seemingly useless command that repeats its input as its output.

drasnor@jormungand ~ $ echo ECHO…Echo…echo…
drasnor@jormungand ~ $

We’ll see how this can be useful momentarily.

Piping and Redirection

Piping and redirection are features GNU/Linux offers to direct command output to somewhere other than the console that called the command. These features are some of the most powerful available on the command line and are among the main reasons people use it at all.

Piping directs the output from one command to the input of another. For example, maybe you have a lot of files in a directory and ls only shows you the last page of files since the rest scrolled past faster than you can see. Most GNU/Linux machines have a paginator (a program that scrolls output a page at a time) installed, usually either the programs more or less, sometimes both.

drasnor@jormungand ~ $ ls | more

< ... >

Pressing the spacebar scrolls output by one page and enter by one line.

Piping can be accomplished with many programs. In fact, complex scripts exist which pipe output from multiple commands in sequence to several programs in one line. These kinds of scripts are common in software development, server administration, and system configuration.

Redirection takes the output of some command and directs it to a file. There are a couple of ways to do this:

drasnor@jormungand ~ $ echo “Meow” > cat.txt

This command creates or replaces an existing file named cat.txt whose contents are Meow. The following command appends the line “Rawr” to an existing cat.txt or creates one if it doesn’t exist:

drasnor@jormungand ~ $ echo “Rawr” >> cat.txt

GNU/Linux treats every single thing as a file including directories, devices (like your processor, memory, hard drive, sound card, etc.) as well as more oddball things. There exists a special file named /dev/null that is like a black hole for data:

drasnor@jormungand ~ $ echo “Honey, I’m really sorry about last night, it was all a misunderstanding and I’m willing to talk it over with you when you get home” >> /dev/null
drasnor@jormungand ~ $

Remember, if you direct anything to /dev/null it’s the same as if it never happened at all.

cat – Meow

cat is a useful tool for displaying the contents of files. cat concatenates the contents of some input file into its output:

drasnor@jormungand ~ $ cat cat.txt
drasnor@jormungand ~ $ cat /dev/null
drasnor@jormungand ~ $

All sorts of uses exist for cat. Use your imagination.

grep – Not What You Do To Your Significant Other:

grep is a pattern matching utility useful for finding specific things in large quantities of output. For instance, when checking the system event log with dmesg maybe you’re only interested in USB events like whether or not GNU/Linux detected that thing you just plugged in:

drasnor@jormungand ~ $ dmesg | grep usb
usbcore: registered new driver hiddev
input: USB HID v1.10 Mouse [Logitech USB-PS/2 Optical Mouse] on usb-0000:00:02.0-1
input: USB HID v1.10 Keyboard [Logitech Logitech USB Keyboard] on usb-0000:00:02.0-2
input: USB HID v1.10 Mouse [Logitech Logitech USB Keyboard] on usb-0000:00:02.0-2
hiddev96: USB HID v1.10 Device [American Power Conversion Back-UPS RS 1500 FW:8.g8 .D USB FW:g8 ] on usb-0000:00:02.0-4
usbcore: registered new driver usbhid
usb 1-3.1.3: new low speed USB device using ehci_hcd and address 11
input: USB HID v1.00 Joystick [LTS PSX/USB Pad] on usb-0000:00:02.1-3.1.3
drasnor@jormungand ~ $

I chose not to show the full dmesg output since it is several pages long. Any time you need to match a pattern, grep it.

man – When You Need Help, Ask The Man:

man is short for manual and is the best way to find out about anything you don’t understand:

drasnor@jormungand ~ $ man man
Formatting page, please wait…

man – format and display the on-line manual pages

man [-acdfFhkKtwW] [–path] [-m system] [-p string] [-C
config_file] [-M pathlist] [-P pager] [-B browser] [-H
htmlpager] [-S section_list] [section] name

man formats and displays the on-line manual pages. If you specify section, man only looks in that section of the manual. name is normally the name of the manual page, which is typically the name of a command, function, or file. However, if name contains a slash (/) then man interprets it as a file specification, so that you can do man ./foo.5 or even man /cd/foo/bar.1.gz.

drasnor@jormungand ~ $

Unfortunately, man can only help you with things it knows about:

drasnor@jormungand ~ $ man woman
No manual entry for woman
drasnor@jormungand ~ $

su – The Power Is Yours

Earlier I mentioned that it is bad practice to log in as root since every process you start runs in privileged mode. However, being root is necessary to make any significant change to the system. The solution is su, a command that grants root privileges to the user that calls it and gives root‘s password.

drasnor@jormungand ~ $ su
jormungand drasnor #

Note the #. Any commands from this prompt are executed in privileged mode and all your currently-running tasks keep running in their original unprivileged mode. When you’re done exercising your ultimate power and authority, simply type exit to return to the ranks of mere users.

jormungand drasnor # exit
drasnor@jormungand ~ $

Process Control

ps – Where Are Those Processes?

When you need to see what processes (programs and services) are running on your machine, ps can tell you. Called simply from a terminal:

drasnor@jormungand ~ $ ps
6670 pts/1 00:00:00 bash
6854 pts/1 00:00:00 ps
drasnor@jormungand ~ $

The output includes only processes owned by the user initiated in the terminal that called it. To get a list of all processes running owned by anyone running anywhere, use ps -A:

drasnor@jormungand ~ $ ps -A

EDIT NOTE: There are a lot of processes running on this machine, so I removed some items from the list.

7237 ? 00:00:00 cron
7333 ? 00:00:01 gdm
7336 ? 00:25:07 X
7355 ? 00:00:00 foldingathome
7365 ? 00:00:02 gnome-session
7399 ? 00:01:54 metacity
7437 ? 00:09:11 gaim
7456 ? 00:00:00 thunderbird
7461 ? 00:00:03 xscreensaver
8148 ? 00:00:00 firefox
26771 ? 00:00:00 xmms
28819 ? 00:00:00 hotkeys
6542 ? 00:00:00 FahCore_7a.exe
6608 ? 00:00:00 soffice
6668 ? 00:00:01 gnome-terminal
6670 pts/1 00:00:00 bash
6755 ? 00:00:00 FahCore_78.exe
6859 pts/1 00:00:00 ps

The output consists of the PID or process ID, the TTY or terminal that initiated the process, the cumulative CPU time on the process in hh:mm:ss and the process name. Note that only bash and ps are running on a known terminal. All the rest were called by the system on a nonexistent terminal (system processes).

kill – When a Program Crashes

When a program or process goes out to lunch for an indeterminate period, kill can force the process to quit. kill takes the PID of the process and asks it politely to terminate like so:

drasnor@jormungand ~ $ ps -a | grep jscalibrator
6961 pts/2 00:00:00 jscalibrator
drasnor@jormungand ~ $ kill 6961
drasnor@jormungand ~ $ ps -a | grep jscalibrator
drasnor@jormungand ~ $

In this example I had jscalibrator (a program that helps set up joysticks) running in another terminal. jscalibrator was still running normally and answered kill appropriately. However, some processes that are really crashed need a little extra help in the form of kill -9:

drasnor@jormungand ~ $ ps -a | grep more
6950 pts/1 00:00:00 more
drasnor@jormungand ~ $ kill 6950
drasnor@jormungand ~ $ ps -a | grep more
6950 pts/1 00:00:00 more
drasnor@jormungand ~ $ kill -9 6950
[1]+ Killed cat daily.txt | more
drasnor@jormungand ~ $

In this case, more wasn’t really crashed but instead in a position where it couldn’t answer the original kill signal. How this is accomplished is a little bit too advanced for this primer.

killall – When a Program, Its Processes, and All Its Friends Crash

Some programs spawn several child processes for various reasons. When such a program crashes it can be painful to go through and kill each process individually. Instead use killall:

drasnor@jormungand ~ $ ps -A | grep thunderbird
7452 ? 00:00:51 thunderbird-bin
7453 ? 00:00:00 thunderbird-bin
7454 ? 00:00:04 thunderbird-bin
7456 ? 00:00:00 thunderbird-bin
drasnor@jormungand ~ $ killall thunderbird-bin
drasnor@jormungand ~ $ ps -A | grep thunderbird
drasnor@jormungand ~ $

The more astute among you have already realized that killall can also be used on individual processes when you know what they’re named. This can be nice if you’re too lazy to look up the PID in ps.


By now you should be at least conversant with the GNU/Linux command line. While many tasks can be accomplished in a GUI these days and more still each day, other tasks are easier and faster on the command line and some cannot be done in the GUI at all. Understanding the command line is the first step to being able to help yourself learn GNU/Linux and being able to get help from others intelligently.

If you’re looking for a good book on learning more advanced command line techniques and the basic structure of GNU/Linux, I would recommend

The No B.S. Guide to Linux
Bob Rankin. No Starch Press; 1997. ISBN: 1886411042

It’s a little dated on its treatment of the GUI but all the console and basic information is still good.

LinuxQuestions.org Online Man Pages at http://man.linuxquestions.org/

Please, leave comments on this article in our Alternative OS forum. Thanks for visiting Short-Media!


Howdy, Stranger!

You found the friendliest gaming & tech geeks around. Say hello!