In the early years of public internet usage, before the days of PPP and SLIP (anyone else remember using a SLIP client to get IP connectivity??), one of the only ways to get connected from home was to dial in to a *NIX shell account using a Terminal Emulator application. To many people, their first exposure to the “internet” involved a blinking cursor and a plethora of confusion as their “dir” command refused to work.
That method of internet access hasn’t been popular in quite some time, but regardless, the ancient art of staring blankly at the command line is making somewhat of a comeback through another avenue. With the popularity of OSX, Linux-based ultra portables and “friendly” Linux distributions such as Ubuntu, more and more people are being exposed to environments where Bash is the most common way of performing non-GUI operations.
“What’s that?”, I hear you say, “Non-GUI Operations? But I’m using the latest version of Friendlynix, the friendliest Linux distribution in the world! Can’t I do everything through the GUI?”. For the most part, yes. However, there are going to be times when you need to peek “under the covers”, and it’s best to be prepared lest you be shocked and disturbed by what you find. *NIX variants may have lost a lot of their rough edges, but it’s not all icecream and cakes just yet.
So let’s start with the basics. A *NIX style file system is completely different to the C:\ drive orientated view found in Windows. Everything starts from a single root directory, which lives at “/”. All your devices, including DVD Drives, USB sticks, and hard drives, live as branches of this directory. If you’re interested, you should look into device mounting, but for the sake of this conversation it’s enough to know that the top of your file system is always “/” and everything else can be found below it. Another thing to note is that most *NIX file systems are case sensitive. This means that, to the file system, “MySpecialFile.txt” is not the same as “myspecialfile.txt”.
One of the most important things you’ll need to do once you pop open your terminal of choice is get your bearings, as you won’t be comfortable until you get a feeling for where you sit in relation to everything else. Depending on your terminal setup, this may already be shown to you as part of the prompt, but if it is not then you’ll want to use a command called pwd, which means “print working dir”.
garrys@GAMBIT:~$ pwd
/home/garrys
Here it is telling me that I’m currently in the “/home/garrys” directory. This is my home directory, and is quite often your starting point for a new shell session. Don’t worry about the “garrys@GAMBIT:~$”. That’s my Bash prompt telling me who I’m logged on as, the machine that I’m logged on to and the current working directory. “~” is effectively a shortcut for your home directory, but I’ll get into that a little later.
Now that we know where we are, we’ll want to get a look at our surroundings. The ls command is the *NIX equivalent of good old dir, and the source of much confusion for recent DOS converts. It stands for “list directory contents”, and that’s exactly what it does.
garrys@GAMBIT:~$ ls
amsn_received Music squeak.image
argo.user.properties My GCompris SqueakV39.sources
autosave.xmi nautilus-debug-log.txt temp
Desktop paw.metafile Templates
Documents Pictures uml_generated_code
Examples Public Videos
GNUstep runtime-EclipseApplication workspace
gpodder-downloads squeak.changes
Now, there are a few arguments for ls that you should be aware of. The actual format of the ls command is:
ls [OPTIONS] [FILE]
where [OPTIONS] is, for the sake of this conversation, a string starting with “-” and [FILE] is a filter that you would like to apply to restrict your query. Both [OPTIONS] and [FILE] are optional. [OPTIONS] represents a series of options that you can apply to your command to affect the outcome. An important thing to note is that these options can be combined, which makes for a pretty powerful little tool.
One of the most useful options you can apply is the list option, “l”. It formats the output in a one item per row list, and also presents additional information on each entry, including file size. You would execute it as follows.
garrys@GAMBIT:~$ ls -l
total 16500
drwx------ 2 garrys garrys 4096 2008-05-13 20:10 amsn_received
-rw-r--r-- 1 garrys garrys 1439 2008-07-04 09:42 argo.user.properties
-rw------- 1 garrys garrys 18067 2008-07-14 20:34 autosave.xmi
drwxr-xr-x 15 garrys garrys 4096 2008-07-04 18:44 Desktop
drwxr-xr-x 8 garrys garrys 4096 2008-07-14 18:01 Documents
lrwxrwxrwx 1 garrys garrys 26 2007-12-02 09:07 Examples -> /usr/share/example-content
drwxr-xr-x 3 garrys garrys 4096 2008-07-13 21:10 GNUstep
drwxr-xr-x 5 garrys garrys 4096 2008-07-05 19:55 gpodder-downloads
ls in it’s base form tries to be helpful by hiding various files from you, such as those that start with a “.” character. If you’d like to see these, you can use the “a” option (think “all”, as in “show me all files”). Here we’ve combined the “a” and “l” options to show all files in a directory in an item per row list format:
garrys@GAMBIT:~$ ls -la
total 17868
drwxr-xr-x 138 garrys garrys 12288 2008-07-17 00:31 .
drwxr-xr-x 3 root root 4096 2007-12-02 09:07 ..
drwx------ 2 garrys garrys 4096 2008-04-20 23:58 .abuse
drwxr-xr-x 2 garrys garrys 4096 2008-02-22 20:17 .ActiveState
drwx------ 4 garrys garrys 4096 2008-05-30 23:57 .adobe
drwxr-xr-x 4 garrys garrys 4096 2008-01-04 13:50 .alien-arena
-rw-r--r-- 1 garrys garrys 224 2008-05-11 23:53 .alsamodular.cfg
drwx------ 9 garrys garrys 4096 2008-05-28 01:31 .amsn
drwx------ 2 garrys garrys 4096 2008-05-13 20:10 amsn_received
-rw-r--r-- 1 garrys garrys 657 2008-07-15 22:09 .amSynthControllersrc
-rw-r--r-- 1 garrys garrys 116060 2008-07-15 22:09 .amSynth.presets
-rw-r--r-- 1 garrys garrys 159 2008-07-15 22:09 .amSynthrc
-rw-r--r-- 1 garrys garrys 1439 2008-07-04 09:42 argo.user.properties
Notice all the files with full stops at the start? Normally we wouldn’t see these (and rightly so, as they are mostly settings files), but the “a” option makes them visible. There are many more useful options, such as “t” to sort by the modification time and “S” to sort by size, but those should be enough to keep you going for the moment.
After specifying all your options you are able to add an optional filter to limit your results. These filters can make use of wildcards. You will probably find yourself reaching for the “*” character more often than the others. It basically means “match anything and everything”, and is incredibly handy. Using this you could do something like the following to match all text files in a directory:
garrys@GAMBIT:~$ ls *.txt
nautilus-debug-log.txt
As you can see, only files ending in “.txt” were returned. Very useful.
Now that we can look at the contents of a directory, how do we move about? We use the cd command, which means “change directory”. cd is fairly straightforward, as the syntax is extremely simple:
cd [DIRECTORY]
There are a few special directories that you should be aware of. The aforementioned “/”, or root directory, is probably the most important. If you cd to here then you’ll be sitting at the top of your file system. As previously mentioned, “~” is a shortcut for your home directory. If you cd to here from anywhere in the file system then you will be taken straight to your home directory, usually /home/yourusername.
Every directory always contains two entries you can navigate to, “.” and “..”. The first, “.”, refers to the directory itself, so if you cd to this then you’re not going to go anywhere. This is actually extremely useful, as you’ll find out later on, but for the moment we’ll ignore it. “..” refers to the parent directory (the directory “above” your current location in the file system). Technically you could cd to “..” until the end of time, as once you hit the root directory it becomes just like “.”, i.e. “..” in the root directory always refers to the root directory.
# Change directory to the root of your file system
cd /
# Change directory to your home directory
cd ~
# Stay in the current directory
cd .
# Move to the parent directory
cd ..
When moving to an actual directory you simply type the name of the path to that directory. You can either reference the directory from the root of the file system (an absolute path), or use a relative path, which is the location of the directory from your current position. For example:
# Move to the "etc" directory which lives directly under the root directory
cd /etc
# Move to the downloads/graphics directory which is in the directory I'm currently in. Note there's no leading "/" because we want the path to be relative
cd downloads/graphics
We can even get fancy and combine the parent directory “..” with other paths. This allows us to move up in the file system as well as down. For example:
# We're going to use two directories here: /etc and /bin. They both sit one level under the root directory.
garrys@GAMBIT:/$ cd /etc
#Then we can use a relative reference to move to /bin as follows
garrys@GAMBIT:/etc$ cd ../bin
You can also use wildcards with cd. It will pick the first matching path from the wildcard results and attempt to change directory to it.
# Get a list of all the directories starting with "D". The -d option on ls simply tells ls to only print the names of directories, rather than their contents
garrys@GAMBIT:~$ ls -d D*
Desktop Documents
# Change directory to the first wildcard match, which is going to be the Desktop directory
garrys@GAMBIT:~$ cd D*
# Show our full path, just to prove exactly where we are (even though it's shown in the Bash prompt)
garrys@GAMBIT:~/Desktop$ pwd
/home/garrys/Desktop
The most important thing you can ever be taught is how to learn, and the best way to learn about commands on *NIX systems is the man command. It presents manual pages on commands, describing exactly what they do and what syntax you need to use when calling them. Using this command you can find out more information about all those ls options I neglected to mention in the above text.
garrys@GAMBIT:~$ man ls
LS(1) User Commands LS(1)
NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort.
Mandatory arguments to long options are mandatory for short options
too.
--SNIP--
The man command takes up the entire terminal, and pushing escape will not get you out of it, no matter how many times you try. “q” is the magic key to exit a man page. You can also use the arrow keys to move around, and space acts as a “page down” mechanism. One of the coolest things you can do is search within the man page. “/” followed by a character sequence will search the man page for that character sequence. Very handy if you’re hunting through a rather lengthy file for one pesky option.
One of the best things about *NIX based operating systems is the majority of the content on your file system is in plain text format. Storing things like this is actually a key part of the philosophy that UNIX was based on, as it enables programs to play nice with each other on the command line (among other things). So you have all these text files sitting on your computer; how do you get at them? Well, there are a few options, perhaps the simplest being the cat command.
cat is capable of concatenating multiple files together and printing them out to the command line. Technically it sends them a stream called stdout, but that’s a discussion for another day. Basically you give it one or more files (actually you don’t even need to give it a file, but once again that’s a little beyond our discussion here) and it will print the files out, one after another.
garrys@GAMBIT:~$ cat textfile1.txt
This is textfile 1
garrys@GAMBIT:~$ cat textfile2.txt
This is textfile 2
garrys@GAMBIT:~$ cat textfile1.txt textfile2.txt
This is textfile 1
This is textfile 2
That’s fine for small text files, but what about large files? Well, for that you can use less. It presents information page by page, much like man; in fact, it has almost the same syntax as man (q to quit, space to page, “/” to search etc). You can check out it’s man page for a full list of commands. You may also be interested in learning about more, which is basically the predecessor to less. It’s worth knowing simply because you may see it pop up on the web and wonder just exactly what it is.
Most of the commands you’ve executed up until this point have been in your PATH. This means that they are in designated parts of the system that Bash is aware of and knows to look for executables in. A slight problem arises when you try to run an executable file that may be sitting on your Desktop or in your home directory somewhere; namely it won’t find the file you’re after.It can be incredibly frustrating for new users, as the file shows up when using ls. The thing is, for various security reasons you need to provide a full path to any executable that’s not in your PATH.
# List the executable I want, just to show that it's clearly in the local directory
garrys@GAMBIT:~/Desktop$ ls NVIDIA-Linux-x86_64-169.12-pkg2.run
NVIDIA-Linux-x86_64-169.12-pkg2.run
# Try to execute the file without providing a full path
garrys@GAMBIT:~/Desktop$ NVIDIA-Linux-x86_64-169.12-pkg2.run
#Bash tells me that this didn't work because it couldn't find the command
bash: NVIDIA-Linux-x86_64-169.12-pkg2.run: command not found
# The following will work, as I've specified a full command by using the magic "." directory that references the current directory. The added "./" at the start is the key to success here
garrys@GAMBIT:~/Desktop$ ./NVIDIA-Linux-x86_64-169.12-pkg2.run
This is a fairly big difference for people who are used to the Windows command line or DOS, but it’s one that’s extremely important to remember.
So now you can find out where you are, see what’s in your current directory, move about, find out more information about commands and check out the contents of text files. See, the command line is not so scary after all! Next time we’ll check out some basic file and directory manipulation commands and also explore the difference between Windows and *NIX style file permissions.