The BASH Shell
Once you have your Linux system set up you will get your first experience with the Linux shell. The shell is a command-line interface (CLI) to your kernel and hardware. The shell provides a method by which you can communicate to your computer through the keyboard. The shell takes keyboard input, translates it and passes it to the Linux kernel, and then recieves kernel responses, translates and displays them on your screen. All of this will happen behind the scenes and will be invisible to the user. The kernel, or the core of your operating system, requires a shell layer to translate keyboard input into understandable language and format kernel output for screen display. There are a huge number of shells available, but BASH is the most common and will likely be the shell you will see when you log in. Most modern linux distributions will automatically load a graphical user interface (GUI) over the shell as soon as you boot into your system and you may have to search for the shell or terminal icon in order to experience the shell. While you may be tempted to pass over the shell because of pre-conceived notions about the power of a CLI based on your Windows experience. whereas with a Microsoft Windows system the CLI is mainly used for debugging or maintenance and has none of the power of GUI management tools, the Linux system encapsulates all its power in the CLI. Many of the Linux GUI programs available to users are simply front ends that issue shell commands based on button clicks and other program options. In order to utilize the full potential of your Linux system you need to become familiar with the shell. Before we begin that discussion though, it is important to examine the myriad of different shells availabe. Some of the most common are:
sh- Bourne Shell, written by Steve Bourne at AT&T, this is one of the oldest shells in the Unix/Linux world. As a Unix based operating system, Linux has inheirited the Bourne Shell. On most Linux systems this shell won't actually be the original Bourne Shell, but a modern variant that is backwards compatible with the Bourne Shell.
bash- The bash shell was pioneered by the Free Software Foundations GNU project (http://www.gnu.org). Bash is the Bourne Again Shell. While not entirely POSIX compliant, it is the defacto Linux shell.
ash- The A Shell, or ash, by Kenneth Almquist of Berkely is a lightweight Bourne Shell clone which you may find suitable for use on machines that are very tight on memory.1 Resembles the shell used in AT&T System V Unix.
bsh- (actually just a different name for ash)
POSIX-Standards comittees worked over the Korn shell and slightly modified some specifications to define a "standard" shell which systems meeting the POSIX spec. must comply with. On some systems, /bin/sh is actually now a POSIX compliant shell, fully compatible with Bourne shell, but with most of the ksh features. This standard was created partly because the early ksh was not fully 100% backward compatible with sh, and so caused trouble if it simply replaced it.2
csh- The C Shell, written by William Joy at Berkeley (the founder of Sun Microsystems). The C Shell was designed to be a programmers shell providing tools and options useful for programmers. One of the first shells to explore command line history, the C Shell didn't live up to intended potential and has largely fallen out of favor.
ksh- The Korn Shell, written by David Korn of AT&T, was a successful attempt to provide the functionality of C Shell while using a Bourne Shell syntax and maintaining Bourne Shell backward compatibility.
In order to experience the shell you're going to have to either launch a terminal session from an X windows session, or if your system logs you in without starting X then all you have to do is log in. Your shell session will start with a command prompt like this one:
Note that different machines will configure your prompt differently. The $ sign indicates that you are logged in as a regular user. The prompt changes to a pound (#) when you are logged in as root.
Issuing Simple Commands:
Often times there are several different ways to do the same thing. For instance, take the simple command 'who', which tells you what users are logged into the computer:
[jkeane@madirish jkeane]$ who root :0 Oct 21 16:05 jkeane pts/0 Oct 21 16:04 (2f.c5bccf.client.atlantech.net)
The who command shows up that root and jkeane are logged into the system. While this information is useful, we can use various 'flags' with the 'who' command to narrow or broaden the information provided. To figure out which flags we can use and what for we can issue the following command:
[jkeane@madirish jkeane]$ who --help Usage: who [OPTION]... [ FILE | ARG1 ARG2 ] -H, --heading print line of column headings -i, -u, --idle add user idle time as HOURS:MINUTES, . or old -l, --lookup attempt to canonicalize hostnames via DNS -m only hostname and user associated with stdin -q, --count all login names and number of users logged on -s (ignored) -T, -w, --mesg add user's message status as +, - or ? --message same as -T --writable same as -T --help display this help and exit --version output version information and exit If FILE is not specified, use /var/run/utmp. /var/log/wtmp as FILE is common. If ARG1 ARG2 given, -m presumed: `am i' or `mom likes' are usual. Report bugs to <email@example.com>.
As you can see there are all sorts of flags that we can use. For starters lets try the '-H' flag, issueing the following command:
[jkeane@madirish jkeane]$ who -H USER LINE LOGIN-TIME FROM root :0 Oct 21 16:05 root pts/1 Oct 21 16:06 jkeane pts/0 Oct 21 16:04 (2f.c5bccf.client.atlantech.net)
As you can see this gives us a lot more useful information. Using the --help flag on a command will always yield useful information. The '--help' flag is useful, but sometimes it is very cryptic. To get a more complete description of the command we can use the 'man' command. 'man' is the 'manual' command and provides the manual (or how-to information) for a command. Issuing 'man who' gives us the following:
WHO(1) FSF WHO(1) NAME who - show who is logged on SYNOPSIS who [OPTION]... [ FILE | ARG1 ARG2 ] DESCRIPTION -H, --heading print line of column headings -i, -u, --idle add user idle time as HOURS:MINUTES, . or old -l, --lookup attempt to canonicalize hostnames via DNS -m only hostname and user associated with stdin -q, --count all login names and number of users logged on lines 1-25And you have to press the up or down arrows to navigate the manual. Press 'Ctrl+z' or the Control and z key to quit out of the manual viewer so you can get back to your shell prompt. Here's is the full man (or man page) on the 'who' command.
---------------------------------------------------------------- WHO(1) FSF WHO(1) NAME who - show who is logged on SYNOPSIS who [OPTION]... [ FILE | ARG1 ARG2 ] DESCRIPTION -H, --heading print line of column headings -i, -u, --idle add user idle time as HOURS:MINUTES, . or old -l, --lookup attempt to canonicalize hostnames via DNS -m only hostname and user associated with stdin -q, --count all login names and number of users logged on -s (ignored) -T, -w, --mesg add user's message status as +, - or ? --message same as -T --writable same as -T --help display this help and exit --version output version information and exit If FILE is not specified, use /var/run/utmp. /var/log/wtmp as FILE is common. If ARG1 ARG2 given, -m presumed: `am i' or `mom likes' are usual. AUTHOR Written by Joseph Arceneaux and David MacKenzie. REPORTING BUGS Report bugs to <firstname.lastname@example.org>. COPYRIGHT Copyright © 2000 Free Software Foundation, Inc. This is free software; see the source for copying condi tions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. SEE ALSO The full documentation for who is maintained as a Texinfo manual. If the info and who programs are properly installed at your site, the command info who should give you access to the complete manual. GNU sh-utils 2.0.11 October 2000 WHO(1) ----------------------------------------------------------------
You can see that there is a lot of power in this simple command, however using the '--help' and 'man' options outlined above you should be able to navigate this command.
To move around our shell environment we'll need a few simple commands to start. To find out where you are in the directory tree use the 'pwd' or print working directory command like so:
[jkeane@madirish jkeane]$ pwd /home/jkeane
As you can see we're currently in the jkeane directory under the home directory (which is under the root directory). Directory listings always begin with '/' which indicates the root directory or the top of th directory tree. Subsequent directorys are demarcated with a slash ('/'). Now that we know where we are we need to find out what is contained in our directory. We can use the 'ls' or list command to find out what is in our current working directory like so:
[jkeane@madirish jkeane]$ ls 404error.php images/ mail/ test.txt ATOD_proposal.doc img/ Mail_BU/ ticino2.ZIP bl98.jpg.sda.exe img2/ mysql/ tmp/ csmpl244.jpg.sda.exe jkeane neuchatel.ZIP tmp-018fba265482a140/ Desktop/ liloconf.txt personal.php tmp-020f8d143d1a45a7/ HELLO.C lilo.txt tech.php who.txt html@ links.php
AS you can see there is a lot in my directory and its difficult to tell what is what. Using the --help, we can find out a little more about how to use the 'ls' command:
[jkeane@madirish jkeane]$ ls --help Usage: ls [OPTION]... [FILE]... List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuSUX nor --sort. -a, --all do not hide entries starting with . -A, --almost-all do not list implied . and .. -b, --escape print octal escapes for nongraphic characters --block-size=SIZE use SIZE-byte blocks -B, --ignore-backups do not list implied entries ending with ~ -c with -lt: sort by, and show, ctime (time of last modification of file status information) with -l: show ctime and sort by name otherwise: sort by ctime -C list entries by columns --color[=WHEN] control whether color is used to distinguish file types. WHEN may be `never', `always', or `auto' -d, --directory list directory entries instead of contents -D, --dired generate output designed for Emacs' dired mode -f do not sort, enable -aU, disable -lst -F, --classify append indicator (one of */=@|) to entries --format=WORD across -x, commas -m, horizontal -x, long -l, single-column -1, verbose -l, vertical -C --full-time list both full date and full time -g (ignored) -G, --no-group inhibit display of group information -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G) --si likewise, but use powers of 1000 not 1024 -H same as `--si' for now; soon to change to conform to POSIX --indicator-style=WORD append indicator with style WORD to entry names: none (default), classify (-F), file-type (-p) -i, --inode print index number of each file -I, --ignore=PATTERN do not list implied entries matching shell PATTERN -k, --kilobytes like --block-size=1024 -l use a long listing format -L, --dereference list entries pointed to by symbolic links -m fill width with a comma separated list of entries -n, --numeric-uid-gid list numeric UIDs and GIDs instead of names -N, --literal print raw entry names (don't treat e.g. control characters specially) -o use long listing format without group info -p, --file-type append indicator (one of /=@|) to entries -q, --hide-control-chars print ? instead of non graphic characters --show-control-chars show non graphic characters as-is (default unless program is `ls' and output is a terminal) -Q, --quote-name enclose entry names in double quotes --quoting-style=WORD use quoting style WORD for entry names: literal, locale, shell, shell-always, c, escape -r, --reverse reverse order while sorting -R, --recursive list subdirectories recursively -s, --size print size of each file, in blocks -S sort by file size --sort=WORD extension -X, none -U, size -S, time -t, version -v status -c, time -t, atime -u, access -u, use -u --time=WORD show time as WORD instead of modification time: atime, access, use, ctime or status; use specified time as sort key if --sort=time -t sort by modification time -T, --tabsize=COLS assume tab stops at each COLS instead of 8 -u with -lt: sort by, and show, access time with -l: show access time and sort by name otherwise: sort by access time -U do not sort; list entries in directory order -v sort by version -w, --width=COLS assume screen width instead of current value -x list entries by lines instead of by columns -X sort alphabetically by entry extension -1 list one file per line --help display this help and exit --version output version information and exit By default, color is not used to distinguish types of files. That is equivalent to using --color=none. Using the --color option without the optional WHEN argument is equivalent to using --color=always. With --color=auto, color codes are output only if standard output is connected to a terminal (tty). Report bugs to <email@example.com>.
As you can see there are a lot of options we can use with ls. Lets use the -l for long list entries:
[jkeane@madirish jkeane]$ ls -l total 218160 -rw-r--r-- 1 jkeane jkeane 2363 Jul 25 09:13 404error.php -rw-r--r-- 1 jkeane jkeane 67072 Jul 11 22:59 ATOD_proposal.doc -rw-r--r-- 1 jkeane jkeane 311352 Sep 18 09:34 bl98.jpg.sda.exe -rw-r--r-- 1 jkeane jkeane 251960 Sep 17 08:19 csmpl244.jpg.sda.exe drwxrwxr-x 3 jkeane jkeane 4096 Aug 14 16:04 Desktop/ -rw-r--r-- 1 jkeane jkeane 104 May 11 1989 HELLO.C lrwxrwxrwx 1 jkeane jkeane 13 May 20 04:03 html -> /var/www/html/ -rw-r----- 1 jkeane jkeane 170098320 Jun 25 09:48 jkeane -rw-rw-r-- 1 jkeane jkeane 27947 Oct 1 09:31 liloconf.txt -rw-rw-r-- 1 jkeane jkeane 8076 Oct 1 09:31 lilo.txt -rw-r--r-- 1 jkeane jkeane 7438 Oct 1 10:50 links.php drwx------ 2 jkeane jkeane 4096 Oct 1 17:49 mail/ drwxr-xr-x 2 root jkeane 4096 Sep 27 08:28 Mail_BU/ drwxr-xr-x 6 root jkeane 4096 Sep 27 08:27 mysql/ -rw-rw-r-- 1 jkeane jkeane 23670730 Jun 25 17:22 neuchatel.ZIP -rw-r--r-- 1 jkeane jkeane 5889 Sep 24 12:33 personal.php -rw-r--r-- 1 jkeane jkeane 11094 Oct 1 10:51 tech.php -rw-r--r-- 1 root root 0 Jun 25 09:47 test.txt -rw-rw-r-- 1 jkeane jkeane 24124379 Jun 25 17:10 ticino2.ZIP drwx------ 2 jkeane jkeane 4096 May 10 07:17 tmp/ drwx------ 3 jkeane jkeane 4096 May 21 06:01 tmp-018fba265482a140/ drwx------ 3 jkeane jkeane 4096 May 21 06:00 tmp-020f8d143d1a45a7/ -rw-rw-r-- 1 jkeane jkeane 2105 Oct 21 16:11 who.txt
Wow! Thats a lot more information than before. Note that you can string flags together, so that 'ls -l -a' is the same thing as 'ls -la'. A lot of these entries above look strange and bear some explaining. The first column is the file or directory permissions (we'll get more into that later), the second column is the number of sub-directories under the directory (files give a '1' value for this column), the third column is the user (see permissions) the fourth is group (a permission also), the fifth is the size, the sixth colun is the datestamp and the last column is the actual name of the file or directory. You can tell the difference between files and directories in two ways. The first way is to look for a '/' after the name, the second is to look for a 'd' in the first column. Many files in this directory have extensions, but file extensions aren't required in Linux like they are in Windows, so these may be misleading. You'll also notice one file named html -> /var/www/html/, this is actualy a symbolic link named 'html' but that points to '/var/www/html'.
cd is the 'change directory' command. It is the most useful command for navigating your directory tree. To change into a directory simply type 'cd ' and then the directory name. For instance, to chance into the 'tmp' directory, issue a 'cd tmp' command. To move up one directory use 'cd ..' and to move up two directories issue 'cd ../..'. You can combine cd directives, so, for instance if you wanted to move up one directory, down into a tmp directory and into a subdirectory 'prog' inside tmp you can issue 'cd ../tmp/prog' and you'll navigate on over. Remember to use 'pwd' to check your location. If you ever get lost simply issue a 'cd' and you'll return to your home directory.
Some more useful BASH commands:
Cat is a useful output program that will show you the contents of a file. For instance, issuing a 'cat who.txt' will print out the contents of the file 'who.txt'. Cat is very useful for searching. By issuing the command
cat who.txt | grep 'GNU'
Will print out the one line in the who.txt program with the word 'GNU'. (more on the grep command and the pipe (|) later).
Use the touch command to update a file's datestamp. For instance, using 'touch myfile.txt' will update the datestamp on the file myfile.txt to the system date. touch can also be used to create a file. Issuing a 'touch myfile.txt' command if myfile.txt does not exist in the current directory will create a new blank file named myfile.txt with the current timestamp.
rm is the command used to delete files and folders. Be careful with the rm command! If you wanted to delete the file 'who.txt' you could issue an 'rm who.txt' and delete it. It is safer to use the '-i' flag with rm (for interactive) as it will prompt you as you are deleting. You can use wildcards in an 'rm'. For instance if you issue 'rm *.txt' you can delete all the files with a '.txt' extension. Note that the '*' is a wildcard, meaning the computer will search for all files and folders with the name * (or anything) and '.txt'. Be extremely careful with wildcards and deleting so you don't rm anything important.
mkdir is the command for creating a directory. If you want to create a new directory named myfiles you can simply issue the command 'mkdir myfiles' and a new directory with the name myfiles will appear in the current working directory. rmdir
mv old new
mv is the command for moving a file. For instance, if I wanted to move the file 'who.txt' into a subdirectory named 'myfiles' I would issue a 'mv who.txt /myfiles' and the file would be moved.
cp filelocation newfilelocation
cp is the command for copy. This can be used to copy files from one location to another while leaving the original. For instance if I wanted to copy the 'who.txt' file into the subdirectory myfiles I would issue a 'cp who.txt myfiles/' and the file would copy into the subdirectory.
find is a useful locating command. For instance if I wanted to find all the files with a '.txt' file extention I could issue a 'find *.txt' and get a listing of all the text files in my directory.
whereis (binary, source, or man file)
whereis is a useful searching tool for locating binaries, sources and man pages. This is very useful if you are searching for the location of a specific program on your computer. For instance, if you wish to find the 'cat' command, you can issue a 'whereis cat' and get a listing of the binary, its source files (if any) and the location of the man pages.
ln -s old new
ln is the 'link' command. Very useful for creating shortcuts. For instance if you have a directory in your home directory that you have to access a lot and don't want to type the full path (for instance /myfiles/myimages/outdoor/), you can make a link. Type 'ln -s myfiles/myimages/outdoor/ outdoor' and you create a new 'virtual' directory that links to the outdoor directory!