3.2. Using the Command LineWhen you use the Linux command line, you're opening what can be thought of as an alternative window to the operating systeman alternative window through which you have access to much more powerful, lower level operating system functions. Graphical tools don't provide that power. A graphical environment is merely a high-level abstraction of an operating system environment, and the icons and menus to which we're all so accustomed provide only limited access into that environment. Those icons and menus represent operating system functions, but they're not the actual functions. In other words, graphical interfaces provide a limited, additional layer between operator and operating system, in which a restricted range of functions are represented by pretty pictures. To administer your Web server with maximum efficiency, it's useful to be able to work at the same level as your system. Tip: When we talk about "high level" and "low level" functions, we imply a hierarchy of functionality. Functions of the lowest level communicate with the kernel directly, and therefore have great power and flexibility; higher level tools do more work themselves, offering more functionality and increased safety. Compare, for example, the low level rm command with the higher level Trash functionality in Nautilus. rm simply deletes a file: it's quick and easy, but there's no easy or guaranteed way to recover that file . Nautilus doesn't provide you with such functionality. It insists that you move files to the Trash, effectively marking the file for potential deletion. The deletion itself doesn't occur until you go to the desktop and empty the trash. 3.2.1. Logging in as rootWe've already talked about logging into Linux as root. To do so from the GNOME terminal, you'll enter the su (switch user) command . [kermit@swinetrek ~]$ su Password: You'll be prompted for the root password. Once you've entered it, you'll gain full access to the system: computing omnipotence! Use it wisely. Although there are certain things that can only be done as root, including many of your system administration tasks, it's important to observe good Linux hygiene: don't remain logged in as root any longer than you need to . Every Linux administrator has a horror story of a time when, logged in as root, he or she mistyped a command and deleted everything on the machine (or some similar calamity). You want to avoid such disasters. Be careful, and don't stay logged in as root if you don't need to be. To switch back to your standard user account, use the exit command. 3.2.2. Some Practical ExamplesLet's look at a few examples of the command line in action. 3.2.3.1. Orienting yourself with the pwd CommandIn Nautilus, we can have multiple folder windows open at once. However, when using the command line, we can only work within one directory at a time. That active directory is called the working directory . To find out which directory you're currently in, use the pwd (print working directory) command. [kermit@swinetrek ~]$ pwd /home/kermit Tip: Your home directory, /home/username, is often referred to as ~ . Did you notice the ~ in the command prompt? It indicates that you're currently in your home directory. As we begin to navigate the filesystem, we'll see this command prompt change to reflect the name of the directory in which we're working. Thus, we won't have to constantly enter pwd to find out where we are. 3.2.3.2. Listing Files with the ls CommandThe ls (which stands for list) command, used by itself, lists the contents of the working directory. [kermit@swinetrek ~]$ ls Desktop Hello World.txt You can retrieve a list of the files in another directory by adding the directory name to the command line. For example, ls / will return a listing of everything in the root directory. [kermit@swinetrek ~]$ ls / bin dev home lost+found misc net proc sbin srv tmp var boot etc lib media mnt opt root selinux sys usr Using ls by itself will show you the names of the files contained in a folder, but little more. To view all of the files' details, we can add the -l option to the command, which returns a longer listing. [kermit@swinetrek ~]$ ls -l total 16 drwxr-xr-x 2 kermit kermit 4096 Sep 5 14:21 Desktop -rw-rw-r-- 1 kermit kermit 13 Sep 8 07:30 Hello World.txt There's plenty of information here.
ls -l is so useful that Fedora Core includes a built-in shortcut to it: ll . Your home directory will contain a number of hidden files . In Linux, we can hide a file by starting its filename with a period: if we changed the name of Hello World.txt to .Hello World.txt, it would become hidden. It's in these hidden files that programs store user-specific configuration information. To see hidden files, use the all option (-a), which can be use in conjunction with the -l option, or as an option to ll. [kermit@swinetrek ~]$ ll -a total 212 drwx------ 13 kermit kermit 4096 Sep 8 09:16 . drwxr-xr-x 5 root root 4096 Sep 6 13:48 .. -rw------- 1 kermit kermit 5 Sep 8 06:21 .bash_history -rw-r--r-- 1 kermit kermit 24 May 10 10:15 .bash_logout -rw-r--r-- 1 kermit kermit 191 May 10 10:15 .bash_profile -rw-r--r-- 1 kermit kermit 124 May 10 10:15 .bashrc drwxr-xr-x 2 kermit kermit 4096 Sep 5 14:21 Desktop -rw------- 1 kermit kermit 26 Sep 6 14:20 .dmrc drwxr-x--- 2 kermit kermit 4096 Sep 6 14:21 .eggcups -rw-r--r-- 1 kermit kermit 438 May 18 01:23 .emacs -rw------- 1 kermit kermit 16 Sep 6 14:28 .esd_auth drwx------ 4 kermit kermit 4096 Sep 6 14:31 .gconf drwx------ 2 kermit kermit 4096 Sep 6 14:31 .gconfd drwxrwxr-x 3 kermit kermit 4096 Sep 6 14:21 .gnome drwx------ 7 kermit kermit 4096 Sep 6 14:31 .gnome2 drwx------ 2 kermit kermit 4096 Sep 6 14:20 .gnome2_private drwxr-xr-x 2 kermit kermit 4096 Sep 6 14:21 .gstreamer-0.8 -rw-r--r-- 1 kermit kermit 120 May 22 15:18 .gtkrc -rw-rw-r-- 1 kermit kermit 134 Sep 6 14:20 .gtkrc-1.2-gnome2 -rw-rw-r-- 1 kermit kermit 13 Sep 8 07:30 Hello World.txt -rw------- 1 kermit kermit 0 Sep 6 14:31 .ICEauthority drwx------ 3 kermit kermit 4096 Sep 6 14:21 .metacity drwx------ 2 kermit kermit 4096 Sep 6 14:22 .mozilla drwxr-xr-x 3 kermit kermit 4096 Sep 6 14:21 .nautilus -rw------- 1 kermit kermit 50 Sep 6 14:26 .recently-used -rw------- 1 kermit kermit 497 Sep 6 14:21 .rhn-applet.conf -rw------- 1 kermit kermit 66 Sep 8 09:16 .xauth3R8EvP -rw-r--r-- 1 kermit kermit 658 Jan 16 2005 .zshrc At the top of this file listing appear two directories, named . and .. . These are shortcuts to the current directory and the parent directory, respectively. We'll look at these in the next section. 3.2.3.3. Moving around the Filesystem with the cd CommandThe cd command stands for change directory. It changes the current working directory to the one specified immediately after the command. [kermit@swinetrek ~]$ cd /etc/httpd/ [kermit@swinetrek httpd]$ Used by itself, the cd command returns you to your home directory . [kermit@swinetrek httpd]$ cd [kermit@swinetrek ~]$ The commands cd /home/kermit and cd ~ do the same thing. You can move to the working directory's parent directory using the cd .. command. [kermit@swinetrek ~]$ cd .. [kermit@swinetrek home]$ 3.2.3.4. Printing with the echo and cat CommandsThe echo command simply sends output to the screen. [kermit@swinetrek ~]$ echo "Hello, World\!" Hello, World! Tip: Certain characters are reserved for special use on the command line, such as !. However, you'll often want to use these characters in command options or in filenames. To use these characters, you must escape them, that is, prefix them with a backslash (\) character . If you use spaces in filenames, you'll need to escape the spaces when dealing with those filenames on the command line: our file Hello World.txt needs to be accessed as Hello\ World.txt. The cat command opens a file and writes its contents to the screen. [kermit@swinetrek ~]$ cat Hello\ World.txt Hello, World! 3.2.3.5. Copying and Moving Files with the cp and mv CommandsThe copy commandcpcreates a copy of a file. [kermit@swinetrek ~]$ cp Hello\ World.txt Copy.txt [kermit@swinetrek ~]$ ls Desktop Hello World.txt Copy.txt Here, we've created an exact copy of Hello World.txt called Copy.txt. We can create a copy of a file in a different directory like so: [kermit@swinetrek ~]$ cp Hello\ World.txt \ >/var/backup/Hello\ World.txt [kermit@swinetrek ~]$ Note: Because some commands are too long for the page width of this book, I have split them into multiple lines. If you ever want to do this on the command line, you need to end each line with a space followed by a backslash (\). When you press Enter when a line that ends this way, you'll get a > prompt to enter the rest of the command. Since you're not writing a book, you can just type these long commands as one long line (the terminal will wrap the command to the next line automatically as you type it). You can use cp to copy an entire directory hierarchy. The following command will create a /var/backup/kermit directory, which will contain a copy of all of kermit's files. [kermit@swinetrek ~]$ cp -r /home/kermit/ /var/backup/ [kermit@swinetrek ~]$ mv (which stands for move) moves a file from one location in the filesystem to another. [kermit@swinetrek ~]$ mv Hello\ World.txt Moved.txt [kermit@swinetrek ~]$ In the above example, the file Hello World.txt is being moved to a new file named Moved.txt in the same directory; effectively, we're just renaming the file. Unlike the cp command, when the mv command is used, the original file is not retained in its original location. To move the file to another directory, the command could be executed like so: [kermit@swinetrek ~]$ mv Hello\ World.txt /var/backup/ [kermit@swinetrek ~]$ 3.2.3.6. Switching Users with the su and exit CommandsWe've already seen that su, used by itself, logs into the root account, and prompts you for the root user password: [kermit@swinetrek ~]$ su Password: [root@swinetrek kermit]# Note: Note the changes to the prompt when you switch over to root: the character at the end of the prompt changes from a $ to a # to indicate that you're logged in as root. If you were in your home directory, the current directory in the prompt would change from ~ to your old username. This indicates that you're no longer your normal user in your home directory: you're root in another user's home directory. root's home directory is /root. To switch back to your original user, use the exit command : [root@swinetrek kermit]# exit exit [kermit@swinetrek ~]$ You can use su to switch to any other user, as long as you know that user's password. [kermit@swinetrek ~]$ su gonzo Password: [gonzo@swinetrek kermit]$ 3.2.3.7. Changing File Permissions with the chmod CommandWe looked at permissions, and saw how to change them through the GUI, in Chapter 2. You can also change these permissions from the command line using the chmod (change mode) tool. [kermit@swinetrek ~]$ chmod o+w Hello\ World.txt [kermit@swinetrek ~]$ ll total 16 drwxr-xr-x 2 kermit kermit 4096 Sep 5 14:21 Desktop -rw-rw-rw- 1 kermit kermit 13 Sep 8 07:30 Hello World.txt Here, we've granted all other users write access to Hello World.txt. We told chmod to do this by passing o+w to it. Let's take a look at what that means:
You can also combine these letters. For example, you can use ug-w to revoke write permissions for the user and group. [kermit@swinetrek ~]$ chmod ug-w Hello\ World.txt [kermit@swinetrek ~]$ 3.2.3.8. Deleting Files with the rm CommandAs we've already seen, the rm command removes a file. In the example below, rm would remove the file MyCopy.txt. [kermit@swinetrek ~]$ rm MyCopy.txt [kermit@swinetrek ~]$ In order to remove a directory and everything inside it, we must add the "recursive" (-r) option to the command, like so: [kermit@swinetrek ~]$ rm -r untitled\ folder [kermit@swinetrek ~]$ Ordinarily, you must have write permissions to a file in order to delete it; however, if you have write permissions on the directory containing the file, you can delete files if you confirm the action. If you attempt to delete a file to which you only have read permissions, you'll be asked if you really want to delete that file: [kermit@swinetrek ~]$ rm Read\ Only.txt rm: Remove write-protected regular file 'Read Only.txt'? y [kermit@swinetrek ~]$ To force a deletion without further confirmation, add the -f option to the command. This can be combined with the -r option to delete a write-protected directory, too. [kermit@swinetrek ~]$ rm -rf Read\ Only\ Folder [kermit@swinetrek ~]$ Warning: Use the -f option with the rm command very carefully. When logged in as root, deleting directories or files without confirmation can result in serious damage to your installation. Confirming the deletion provides a safeguard against these accidental deletions. Tip: Possibly the most useful of all command line tools is man, the online manual. If you ever need to find out what a command does or what options are available, just enter man commandname at the command prompt.When reading the manual, the up and down arrow keys scroll through the text, the space bar scrolls through a page at a time, and Q quits the manual and returns you to the command prompt. 3.2.3. Introducing the ShellIn the same way that we can interact with Linux graphically through a desktop environment such as GNOME or KDE, we interact with the Linux command line through a shell. We've been using the shell throughout this chapter; let's now take a look at some of its more advanced features. The default shell in Fedora Core (and, in fact, in most modern Linux systems) is bash , or the Bourne Again Shell. bash is a modern rewrite of the original Bourne shell, sh, which was written in 1977. While other shell environments exist, such as tcsh, csh and ksh, bash has become increasingly popular due to its useful featureset. We'll look in detail at some of those features here. 3.2.4.9. Tab CompletionOne of the most useful features of many modern shells is tab completion. When a partial command or filename is entered on the command line, and the user presses the Tab key, the command or filename will be completed for you. For example, typing cat Hello, followed by Tab, will result in cat Hello\ World.txt being completed at the command line for you. However, typing cd /etc/ht, followed by Tab, doesn't immediately return anything. That's because two directories begin with /etc/ht: /etc/httpd and /etc/htdig. Pressing the Tab key a second time will list the possible options: [kermit@swinetrek ~]$ cd /etc/ht httpd/ htdig/ [kermit@swinetrek ~]$ cd /etc/ht We can use this list to continue typing until we've typed enough characters to identify a single directory; we can then press Tab again to have the filename completed. 3.2.4.10. Command HistoryThe bash shell records a limited history of recently issued commandsup to 1000 by default. You can use the up arrow key to scroll back through the command history, and the down arrow key to scroll forward. When the desired command is found, you can execute it by pressing Enter. To see the full history, simply enter the history command. All your recent commands will be displayed in chronological order, with the oldest at the top. [kermit@swinetrek ~]$ history 1 pwd 2 ls 3 ls / 4 ls -l 5 ll -a 6 cd /etc/httpd/ 7 cd 8 cd .. 9 echo "Hello, World\!" 10 cat Hello\ World.txt 11 cp Hello\ World.txt Copy.txt 12 cp Hello\ World.txt /var/backup/Hello\ World.txt 13 cp -r /home/kermit/ /var/backup/ 14 mv Hello\ World.txt Moved.txt 15 mv Moved.txt /var/backup/ 16 su 17 su gonzo 18 chmod o+w Hello\ World.txt 19 ll 20 chmod ug-w Hello\ World.txt 21 rm Copy.txt 22 rm -r untitled\ folder 23 rm Read\ Only.txt 24 rm -rf Read\ Only\ Folder This history is also searchable. Hitting CtrlR will change the prompt to (reverse-i-search)`':; now, try typing part of one of the commands in your history. The shell will find within the history the most recent command that contains the entered string, and display it. Just hit Enter to execute it, or Esc to return to the normal prompt. In the example below, I've entered Hello and found the last command that involved the file Hello World.txt. (reverse-i-search)`Hello': chmod ug-w Hello\ World.txt Some built-in history shortcuts can further maximize the efficiency with which you utilize the shell history. The !! command will execute the last command in the history file. For example, if the last command entered was ll, !! would re-run that command. [kermit@swinetrek ~]$ !! ll total 16 drwxr-xr-x 2 kermit kermit 4096 Sep 5 14:21 Desktop -rw-rw-r-- 1 kermit kermit 13 Sep 8 07:30 Hello World.txt !partial-command will execute the last command beginning with partial-command. For example, !ech would re-run the last echo command. [kermit@swinetrek ~]$ !ech echo "Hello, World\!" Hello, World! 3.2.4. Programming the ShellThe shell itself can be quite a powerful little programming language. It supports looping, branching, variableseverything that constitutes a worthwhile programming environment. These shell programs, called shell scripts, are just text files on which execute permissions are set. The text files contain commands just like those you'd type on the command line: hello_world.sh
The output of this script is exactly as you'd expect: Hello, World! Let's take a look at some of the shell's more programming language-like features. First, we'll create a new variable in the shell and print its value. [kermit@swinetrek ~]$ COUNTER=0 [kermit@swinetrek ~]$ echo $COUNTER 0 Once the variable COUNTER is created, it's there until you close the terminal window. The value of the variable may change, as you'll see, but the variable itself remains until the terminal session is ended. This is true of any declared shell variable. If we use the increment operator (++) to increment the value of COUNTER, then echo it again, you'll see that the shell does, in fact, track the values of these variables: [kermit@swinetrek ~]$ let COUNTER++ [kermit@swinetrek ~]$ echo $COUNTER 1 Let's build a simple script, called counter_test.sh , that will keep on counting until we tell it to stop by pressing CtrlC. Tip: You can abort any process on the command line by pressing CtrlC. This is referred to as sending the program an interrupt signal.This same keyboard shortcut will throw away a command and start you on a new, blank prompt if you're not happy with what you've typed. The first line of any shell script is what's commonly referred to as the shebang : a pound sign, followed by an exclamation point, followed by the path to the shell.[1]
#!/bin/sh Every shell script must begin with this line. The next line of our script will set a value for the COUNTER variable: COUNTER=0 In other words, we're starting the counter at zero. Next, we'll add a loop to the program. We'll make it an infinite loop, so the user will have to send an interrupt signal to quit the program. while true; do # contents of loop go here done Now all we need to do is define just what it is that the shell is going to do as long as the condition is true: print the value of COUNTER, increment COUNTER, and wait for one second: while true; do echo $COUNTER let COUNTER++ sleep 1; done If you're following along closely, you'll already know what we'll see on the screen: a count up from 0. Here's the script in its entirety: counter_test.sh
We've created a good shell script, but we still have one loose end to tie up before we can run it. For our script to execute, we need to set the appropriate permissions. [kermit@swinetrek ~]$ chmod u+x counter_test.sh [kermit@swinetrek ~]$ Now we can run the script: [kermit@swinetrek ~]$ ./counter_test.sh 0 1 2 3 4 This tells the shell to execute a file named counter_test.sh within the current working directory. You should see the screen start to count from zero, pausing for a second between increments. CtrlC will stop the counting. That's but a small taste of the process of writing a shell script. Remember, as well, that shell scripts can access most of the single commands you'll utilize in your day-to-day Linux use. A script that elegantly combines these tasks into a single executable file can be a thing of beauty and a real time-saver. If you've had previous programming experience, you're likely to find the shell a bit lightweight for programming purposes. Clearly, the shell isn't a powerful development environment. If it doesn't meet your needs, you should probably begin to dig more deeply into powerful scripting languages like Perl. Shell scripts, however, have the advantage of being a good hacker's tool. They're quick, they can accomplish many of the daily administrative tasks you'll face in Linux, and many pieces of each script can be tested directly in the shell prior to being rolled into a script. Further exploration of the possibilities of shell scripting can be found in the detailed online tutorial A Quick Guide to Writing Scripts Using the Bash Shell. 3.2.5. The PATH Environment VariableNow , remember that all of the command line tools are binary files located somewhere in the filesystem: the ls command, for example, actually lives in the directory /bin. But how does the shell know to find /bin/ls when you type ls at the command prompt? The shell looks through all the directories listed in its built-in PATH variable, in search of a file that has the same name as the command you're after. The PATH environment variable for a default Fedora Core installation will look something like this: [kermit@swinetrek ~]$ echo $PATH /usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin So when you type the ls command, the shell would first look for an executable file /usr/kerberos/bin/ls, without success. Is there a /usr/local/bin/ls? No. What about a /usr/bin/ls? Sorry. How about a /bin/ls? Bingo! Remember that, when we ran our counter_test.sh script, we needed to prefix the script filename with ./ to tell the shell that the executable file was in the working directory. If we were to add this directory to the PATH variable, we could simply enter counter_test.sh to run this script regardless of the working directory. Built-in variables such as PATH are known as environment variables . These are the variables that describe the environment in which a process is running. Examples of other environment variables are HOME, which contains the path of the user's home directory, and MAIL, which is the name of the file that stores the user's email. Environment variables work just like normal shell variables, except they can be accessed by programs that are launched from the shell too. To set or modify an environment variable, you must use the export command : [kermit@swinetrek ~]$ export PATH=$PATH:/home/kermit [kermit@swinetrek ~]$ echo $PATH /usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin :/home/kermit/bin:/home/kermit Note how we've used the PATH environment variable's existing value ($PATH) in specifying its new value. This technique allows us to tack an additional directory onto the end of the existing PATH. You can see that the /home/kermit directory has been added to the PATH variable. You should now be able to run counter_test.sh as easily as you'd run ls. [kermit@swinetrek ~]$ counter_test.sh 0 1 2 3 4 Setting the PATH environment variable in this way will allow you to run a shell script from any directory for the remainder of this terminal session, but the modified PATH will be lost as soon as you exit the terminal. In Chapter 4, we'll see how to modify the default PATH used whenever a new shell is launched. |