Introduction to the Basic Unix Shell Commands
|The Unix Shell and the Unix Command Line:
The shell is that portion of Unix that handles the command line by which you enter commands. Unix always has a shell; it doesn't always have a GUI a graphical user interface like a Mac or Windows. (And even when it does, you wouldn't want to try to use it over a low bandwidth connection like a phone modem.) You run other, more interesting programs by asking the shell to run them for you. They may run for hours but when they're done, control of the keyboard and display returns to the shell. So the shell is the "top level" program you deal with on a Unix system. You command the shell to do things for you (like run some other program) by typing and entering commands from the keyboard. To enter a command to the shell, you must see a prompt and a blinking cursor. That is your cue (prompt) that the shell is ready for you to start typing. If you don't see a shell prompt, some other program is running.
Since most commands operate on (do things to
or with) files, you may also have to tell the command
which file(s) to use; so file names (and sometimes other data you type
on the command line) are often referred to as arguments
to commands don't ask me where that word "argument" comes
from in this context (I don't actually know, to tell you the truth).
Thus, commands typically take the form
When you want the shell to execute the command you've typed, hit the "Enter" or "Return" key on your keyboard after typing the file name(s) for any argument(s) first. Nothing will happen until you "Enter" the command you've typed. Until you get more advanced, your entire command (the command name itself followed by the argument(s) you want to give it, if any) must all fit on one line that you must "Enter" only after you type the entire line the way you want it. Note:
More about prompts. Sometimes, like when you're editing a file, your keystrokes will go to another program, not the shell. If you're editing, for example, you're typing input to the editor. (You had to command the shell to run the editor for you, but once the editor started running, you would be typing inputs to it and not to the shell.) Some programs, like the shell, display prompts for you; some don't depends on what the program's for and whether or not it really wants any keyboard input from you. A compiler typically doesn't, for example all your input to the compiler comes from a file you somehow created previously, probably using an editor. So a compiler provides no prompt whatsoever and if you type on your keyboard while the compiler is running, the keystrokes probably just get ignored (by the compiler, they might get saved and fed as input to the shell after the compiler is done, however). An editor accepts keyboard input from you but displays no prompt it just accumulates your keystrokes in a buffer and displays them to let you edit them.
Any program that does prompt you for keyboard input will usually try to pick a distinctive prompt so that you'll be able to tell exactly which program you're talking to. As I said earlier, when discussing commands, each program has its own rules and conventions this is true both for how it is controlled as well as what type of prompt it displays (if any). That's why I and other Unix authors sometimes refer to the "shell prompt" to distinguish it from the prompts provided by other prompting programs. There's nothing all that special about the shell; it's just another program as far as the rest of Unix is concerned a particularly important, useful, and interesting program, but still just another program. (The purpose of the shell program is to provide you a command line interface to the rest of the Unix system.)
Most shell commands can in fact do several different things or do one thing
in several different ways so they accept options, indicated on the command
line by a dash. But they're just that options so there's almost
always a sensible default if you choose not to invoke the option. Many
of the options are pretty useful, however, so you'll want to know a little about
how to find out about them and how to use them. Here's an example:
- cd X indicates that you think there's a sub directory named X located in the current working directory and that you want to move "down" into X, making it the new working directory. (The "down" here assumes you view a directory structure as an upside down tree, as shown in Figure 1, which is how all good Unix folks look at the world.)
- cd X/Y indicates that you think X is a sub directory in the current directory and that X itself has a sub directory named Y. If you're right, after executing the
cd X/Ycommand, the current working directory would be Y (If you're wrong, of course, you'd get some sort of error message.) cd X/Ygoes down two levels, cd X/Y/Zwould go down three levels, and so on.
- Note: cd X/Y and cd X/Y/ are equivalent here (and probably anywhere else where the argument is expected to be a directory name). Since the argument to the cd command is expected to be a directory name, there's no basic file name following the Y that the Y needs to be separated from and there's no ambiguity as to whether Y is a directory name or not. As noted earlier, the trailing / is not really part of the directory name; it's just a separator. So the trailing / makes no difference one way or the other here; but a leading / would be a very different matter indeed; its the name of the root remember, and hence would indicate a fully qualified path name. See the next note, below.
- cd /X/Y/Z ignores the current working directory completely and starts looking for X in the root and then goes down from there, looking for Y within (beneath) X and then Z beneath Y. If it finds all these as expected, the working directory will be set to Z (or to /X/Y/Z, to be precise). cd / changes the working directory to the root, but unless you have super-user privileges, all you can do there is look around; you can't create new directories or files up there. In fact, you probably can't create new directories or files anywhere except within your home directory.
cd ..(that's cd followed by two periods) changes the working directory "up" one level (to what's called the "parent" of the current working directory) unless you're already in the root, which has no parent (weep for the root).
- Syntax like
cd ../X/Yis perfectly valid. It says to go up one level (from whatever the current working directory is) and look there for a directory X containing a sub directory Y. cd .. /.. has the obvious meaning: go to the parent of the parent of the current working directory, and so on.
- If you get really lost, typing just cd with no other data on the line will cause the shell to set the current working directory to your home directory wherever you were started when you logged on.
- Naturally, there's a way to change that so that cd by itself changes you to a default directory different from your home directory; but you really shouldn't be messing around with such things at this point.
- g77 filename.f presumably does the obvious and compiles the Fortran program contained in filename.f Why only presumably? There's not much call for Fortran in modern CS curricula these days so I haven't played with this one at all. From the name (g77) I would guess that it's the old 1977 dialect of Fortran. If you need something newer, contact IT.
- g77 --help gets you a quick list of command line options. Note that just g77 by itself does not give you that usage summary, you have to ask for it with the double-hyphened option --help; I have no idea why.
There's a huge man page for this and it's even available in HTML, but it's vast overkill. All you really need to know is:
- gcc my_program.c compiles the program contained in the source file my_program.c and, if the compilation was successful, places the executable output in a file named a.out, overwriting (destroying) whatever used to be there (if anything).
- gcc, like may other Unix programs, doesn't give you any special indication that it was successful. All you'll see is the appearance of a new shell prompt. If there are problems in the compilation, you'll get error messages; but no problems, no messages. The error messages are straightforward enough. Here's a simple one, for example, from a compilation of a file named "ctime.c":
ctime.c: In function `main':
ctime.c:16: parse error before `='
The first entry on the first line, before the colon, is the name of the file being compiled (ctime.c, in this example). The rest of that first line tells you which function in that file the error messages pertain to. Subsequent lines give you the line numbers (of the file, not the function) containing the errors, plus as much information as the compiler can manage about each error itself. (Usually not too much gcc is freeware; one of the reasons people spend money on more expensive compilers is to get better diagnostic help.)
- To execute your compiled program, just enter a.out as a command name in response to a shell prompt. If that doesn't seem to want to work, enter "./a.out"; if typing the "extra" two characters (./) at the beginning bothers you, learn how to edit your Unix 'PATH' environment variable so that they can be omitted.
- Don't like that default name (a.out)? Use the -o option, gcc -o whatever my_program.c and the executable shows up in the file named whatever; it seems to me that my_program.exe would be a good choice of filename here; but that's a custom (and a good one), not a rule. (As before, to execute my_program.exe, just enter my_program.exe as a command name (in response to a shell prompt).
Entering just the command gcc --help will give you a very brief overview of some of the most important of the hundreds of complicated options that are still totally irrelevant to an undergraduate programming class.
|ls lists the names of the files immediately available to you (to use as arguments to your commands). You couldn't, for example, compile a file whose name you didn't see in response to an ls command.|
- If xyz is a directory name (a fully or partially qualified path),
ls xyzlists the contents of xyz (i.e., it lists all the files in xyz, since a directory is just a file containing the names of other files)
- If xyz is not a directory,
ls xyz tells you whether or not a file named xyz exists. Wildcards make this a very useful command (I'm not explaining wildcards here, but they're in the Intermediate Unix notes when you're ready). ls *.adb would list all your (properly named) Ada programs, for example.
- Lots of other useful options and switches available also (use
man lsto figure them all out). I particularly like ls -FIt shows you which of your files are executable and which are directories by appending a * or a /, respectively, to the name of the file.
|There's no "help" command in Unix; man
is the equivalent. |
- Unix provides security to prevent you from creating things where you shouldn't.
mkdir /my_stuffis a legal command; but you or I don't have the privileges necessary to go creating directories up in the root, so it wouldn't work for us but would for an administrator with super-user privileges. Within and beneath your home directory, however, you can certainly create new directories
|You'll probably want to learn a little about
command, since the output from the man
program is automatically displayed via more. You can run more yourself
Enter man moreto learn more about more (as opposed to some sorts of courses in some universities were you learn more and more about less and less until eventually you know everything there is to know about absolutely nothing, in which case you get to put a Ph.D. after your name ;-)
- pwd displays the directory name, actually; it doesn't print it thus inadvertently demonstrating the antiquity of much of the original Unix. In days of old, our terminals didn't come with CRT screens but horribly slow, noisy, and messy little printers. That's why real programmers (you have to be old to be a real programmer) don't use GUIs. ;-)
|rm file_name does the obvious. Don't do it unless you mean it. There's no "undo", or "trash can" or "recycle bin" in Unix. You remove a file, it's gone forever.|
- If it's an old enough file and your file system is backed up periodically, your system administrator may be able to recover the last backed up version for you. (Any changes between the last backup and your clumsy and ill advised deletion are lost forever, however. And you lose immense face when you go to a system administrator for this; real programmers would rather redo a month's worth of work than admit they made a perfectly human mistake of course their boss probably feels a little differently about it.)
- If this really worries you (you wimp, you), use
rm -i file_name, where the -i option causes Unix to ask if you really want to do that? If you are really, really a worrier, alias rm to rm -iso even if you make a mistake and type the rm without the -i option Unix will still coddle you. You're really, really, super worried? Write a shell script to move any file to a file with some funny convention for its name like a "comma" in front of the old name, so xyz would be moved to ,xyz Then use the Unix 'at' command to remove files with your funny names (e.g., starting with a comma) every midnight. Then alias the renaming script to rm. The result? When you type rm, all that really happens is that the files get renamed and "marked" for later automatic deletion. Still worried? Tough. (Certainly I could give you more options, but your paranoia is exceeding my limited patience.)
- Note: If file_name already exists, its previous contents will be destroyed; so if you're using this command to help you prepare to turn in your homework, don't enter script your_wonderful_program, where your_wonderful_program is the actual name of the source file containing the program you're trying to turn in; if you do, guess what you'll do to your_wonderful_program?
- If you don't specify a file name, the default is typescript, which seems safe enough
- exit kills the current shell, which, for beginners, is normally the login shell unless you're in a script session; so normally exit is the same as logout unless you're in a script session. The point? Make sure you are actually in a scripting session before saying exit; otherwise you'll get logged out.
If you're having trouble visualizing the workings of script, here's a link to another URL with some pictures in it.