CONTENTS |
Before the C shell displays a prompt, it is preceded by a number of processes. See Figure 9.1.
After the system boots, the first process to run is called init; it is assigned process identification number (PID) 1. It gets instructions from a file called inittab (System V) or spawns a getty process (BSD). These processes are responsible for opening up the terminal ports, for providing a place where input comes from (stdin), where standard output (stdout) and error (stderr) go, and for putting a login prompt on your screen. The /bin/login program is then executed. The login program prompts for a password, encrypts and verifies your password, sets up an initial working environment, and then initiates the shell, /bin/csh. The C shell looks in the user's home directory for a file called .cshrc, an initialization file allowing you to customize the C shell environment you will be working in. After executing commands in the .cshrc file, commands in the .login file are executed. The .cshrc file will be executed every time a new C shell is started. The .login file is executed only once when the user logs on, and also contains commands and variables to initialize the user's environment. After executing commands from those files, the percent sign prompt appears on your screen and the C shell awaits commands.
Initialization Files. After the csh program starts, it is programmed to execute two files in the user's home directory: the .cshrc file and the .login file. These files allow users to initialize their own environments.
The .cshrc File. The .cshrc file contains C shell variable settings and is executed every time a csh subshell is started. Aliases and history are normally set here.
(The .cshrc File) 1 if ( $?prompt ) then 2 set prompt = "\! stardust > " 3 set history = 32 4 set savehist = 5 5 set noclobber 6 set filec fignore = ( .o ) 7 set cdpath = ( /home/jody/ellie/bin /usr/local/bin /usr/bin ) 8 set ignoreeof 9 alias m more alias status 'date;du -s' alias cd 'cd \!*;set prompt = "\! <$cwd> "' endif
EXPLANATION
|
The .login File. The .login file is executed one time when you first log in. It normally contains environment variables and terminal settings. It is the file where window applications are usually started. Since environment variables are inherited by processes spawned from this shell and only need to be set once, and terminal settings do not have to be reset for every process, those settings belong in the login file.
(The .login File) 1 stty -istrip 2 stty erase ^H 3 # # If possible start the windows system. # Give a user a chance to bail out # 4 if ( 'tty' == "/dev/console" ) then 5 if ( $TERM == "sun" || $TERM == "AT386" ) then 6 if ( ${?OPENWINHOME} == 0 ) then 7 setenv OPENWINHOME /usr/openwin 8 endif echo "" 9 echo -n "Starting OpenWindows in 5 seconds\ (type Control-C to interrupt)" 10 sleep 5 echo "" 11 $OPENWINHOME/bin/openwin 12 clear 13 logout endif endif
EXPLANATION
|
The Search Path. The path variable is used by the shell to locate commands typed at the command line. The search is from left to right. The dot represents the current working directory. If the command is not found in any of the directories listed in the path, or in the present working directory, the shell sends the message Command not found to standard error. It is recommended that the path be set in the .login file.[1] The search path is set differently in the C shell than it is in the Bourne and Korn shells. Each of the elements is separated by whitespace.
set path = (/usr/bin /usr/ucb /bin /usr .) echo $path /usr/bin /usr/ucb /bin /usr .
The environment variable PATH will display as:
echo $PATH /usr/bin:/usr/ucb:/bin:.
The C shell internally updates the environment variable for PATH to maintain compatibility with other programs (such as the Bourne or Korn shells) that may be started from this shell and will need to use the path variable.
The rehash Command. The shell builds an internal hash table consisting of the contents of the directories listed in the search path. (If the dot is in the search path, the files in the dot directory, the current working directory, are not put in the hash table.) For efficiency, the shell uses the hash table to find commands that are typed at the command line, rather than searching the path each time. If a new command is added to one of the directories already listed in the search path, the internal hash table must be recomputed. This is done by typing
% rehash
(The % is the C shell prompt.) The hash table is also automatically recomputed when you change your path at the prompt or start another shell.
The hashstat Command. The hashstat command displays performance statistics to show the effectiveness of its search for commands from the hash table. The statistics are in terms of "hits" and "misses." If the shell finds most of its commands you use at the end of your path, it has to work harder than if they were at the front of the path, resulting in a higher number of misses than hits. In such cases, you can put the most heavily hit directory toward the front of the path to improve performance.
% hashstat 2 hits, 13 misses, 13%
The source Command. The source command is a shell built-in command, that is, part of the shell's internal code. It is used to execute a command or set of commands from a file. Normally, when a command is executed, the shell forks a child process to execute the command, so that any changes made will not affect the original shell, called the parent shell. The source command causes the program to be executed in the current shell, so that any variables set within the file will become part of the environment of the current shell. The source command is normally used to reexecute the .cshrc or .login if either has been modified. For example, if the path is changed after logging in, type
% source .login or .cshrc
The Shell Prompts. The C shell has two prompts: the primary prompt, a percent sign (%), and the secondary prompt, a question mark (?). The primary prompt is the one displayed on the terminal after you have logged in; it waits for you to type commands. The primary prompt can be reset. If you are writing scripts at the prompt that require C shell programming constructs, for example, decision-making or looping, the secondary prompt will appear so that you can continue onto the next line. It will continue to appear after each newline, until the construct has been properly terminated. The secondary prompt cannot be reset.
The Primary Prompt. When running interactively, the prompt waits for you to type a command and press the Enter key. If you do not want to use the default prompt, reset it in the .cshrc file and it will be set for this and all other C subshells. If you only want it set for this login session, set it at the shell prompt.
1 % set prompt = "$LOGNAME > " 2 ellie >
EXPLANATION
|
The Secondary Prompt. The secondary prompt appears when you are writing on-line scripts at the prompt. Whenever shell programming constructs are entered, followed by a newline, the secondary prompt appears and continues to appear until the construct is properly terminated. Writing scripts correctly at the prompt takes practice. Once the command is entered and you press Enter, you cannot back up, and the C shell history mechanism does not save commands typed at the secondary prompt.
1 % foreach pal (joe tom ann) 2 ? mail $pal < memo 3 ? end 4 %
EXPLANATION
|
After logging in, the C shell displays its primary prompt, by default a percent sign. The shell is your command interpreter. When the shell is running interactively, it reads commands from the terminal and breaks the command line into words. A command line consists of one or more words (or tokens) separated by whitespace (blanks and/or tabs) and terminated with a newline, generated by pressing the Enter key. The first word is the command, and subsequent words are the command's options and/or arguments. The command may be a UNIX executable program such as ls or pwd, an alias, a built-in command such as cd or jobs, or a shell script. The command may contain special characters, called metacharacters, that the shell must interpret while parsing the command line. If the last character in the command line is a backslash, followed by a newline, the line can be continued to the next line.[2]
The Exit Status. After a command or program terminates, it returns an exit status to the parent process. The exit status is a number between 0 and 255. By convention, when a program exits, if the status returned is zero, the command was successful in its execution. When the exit status is nonzero, the command failed in some way. The C shell status variable is set to the value of the exit status of the last command that was executed. Success or failure of a program is determined by the programmer who wrote the program.
1 % grep "ellie" /etc/passwd ellie:GgMyBsSJavd16s:9496:40:Ellie Quigley:/home/jody/ellie 2 % echo $status 0 3 % grep "nicky" /etc/passwd 4 % echo $status 1 5 % grep "scott" /etc/passsswd grep: /etc/passsswd: No such file or directory 6 % echo $status 2
EXPLANATION
|
Command Grouping. A command line can consist of multiple commands. Each command is separated by a semicolon and the command line is terminated with a newline.
% ls; pwd; cal 2001
EXPLANATIONThe commands are executed from left to right until the newline is reached. |
Commands may also be grouped so that all of the output is either piped to another command or redirected to a file. The shell executes commands in a subshell.
1 % ( ls ; pwd; cal 2001 ) > outputfile 2 % pwd; ( cd / ; pwd ) ; pwd /home/jody/ellie / /home/jody/ellie
EXPLANATION
|
Conditional Execution of Commands. With conditional execution, two command strings are separated by two special metacharacters, double ampersand and double vertical (&& and ||). The command on the right of either of these metacharacters will or will not be executed based on the exit condition of the command on the left.
% grep '^tom:' /etc/passwd && mail tom < letter
EXPLANATIONIf the first command is successful (has a zero exit status), the second command after the && is executed. If the grep command successfully finds tom in the passwd file, the command on the right will be executed: The mail program will send tom the contents of the letter file. |
% grep '^tom:' /etc/passwd || echo "tom is not a user here."
EXPLANATIONIf the first command fails (has a nonzero exit status), the second command after the || is executed. If the grep command does not find tom in the passwd file, the command on the right will be executed: The echo program will print tom is not a user here. to the screen. |
Commands in the Background. Normally, when you execute a command, it runs in the foreground, and the prompt does not reappear until the command has completed execution. It is not always convenient to wait for the command to complete. By placing an ampersand at the end of the command line, the shell will return the shell prompt immediately so that you do not have to wait for the last command to complete before starting another one. The command running in the background is called a background job and its output will be sent to the screen as it processes. It can be confusing if two commands are sending output to the screen concurrently. To avoid confusion, you can send the output of the job running in the background to a file or pipe it to another device such as a printer. It is often handy to start a new shell window in the background, so you will have access to both the window from which you started and the new shell window.
1 % man xview | lp& 2 [1] 1557 3 %
EXPLANATION
|
The history mechanism is built into the C shell. It keeps a numbered list of the commands (called history events) that you have typed at the command line. You can recall a command from the history list and reexecute it without retyping the command. The history substitution character, the exclamation point, is often called the bang character. The history built-in command displays the history list.
(The Command Line) % history 1 cd 2 ls 3 more /etc/fstab 4 /etc/mount 5 sort index 6 vi index
EXPLANATIONThe history list displays the last commands that were typed at the command line. Each event in the list is preceded with a number. |
Setting History. The C shell history variable is set to the number of events you want to save from the history list and display on the screen. Normally, this is set in the cshrc file, the user's initialization file.
set history=50
EXPLANATIONThe last 50 commands typed at the terminal are saved and may be displayed on the screen by typing the history command. |
Saving History. To save history events across logins, set the savehist variable. This variable is normally set in the .cshrc file, the user's initialization file.
set savehist=25
EXPLANATIONThe last 25 commands from the history list are saved and will be at the top of the history list the next time you log in. |
Displaying History. The history command displays the events in the history list. The history command also has options that control the number of events and the format of the events that will be displayed. The numbering of events does not necessarily start at one. If you have 100 commands on the history list, and you have set the history variable to 25, you will only see the last 25 commands saved.
% history 1 ls 2 vi file1 3 df 4 ps eaf 5 history 6 more /etc/passwd 7 cd 8 echo $USER 9 set
EXPLANATIONThe history list is displayed. Each command is numbered. |
% history h # Print without line numbers ls vi file1 df ps eaf history more /etc/passwd cd echo $USER set history n
EXPLANATIONThe history list is displayed without line numbers. |
% history r # Print the history list in reverse 11 history r 10 history h 9 set 8 echo $USER 7 cd 6 more /etc/passwd 5 history 4 ps eaf 3 df 2 vi file1 1 ls
EXPLANATIONThe history list is displayed in reverse order. |
% history 5 # Prints the last 5 events on the history list 7 echo $USER 8 cd 9 set 10 history n 11 history 5
EXPLANATIONThe last five commands on the history list are displayed. |
Reexecuting Commands. To reexecute a command from the history list, the exclamation point (bang) is used. If you type two exclamation points (!!), the last command is reexecuted. If you type the exclamation point followed by a number, the number is associated with the command from the history list and the command is executed. If you type an exclamation point and a letter, the last command that started with that letter is executed. The caret (^) is also used as a shortcut method for editing the previous command.
1 % date Mon Feb 8 12:27:35 PST 2001 2 % !! date Mon Feb 8 12:28:25 PST 2001 3 % !3 date Mon Feb 8 12:29:26 PST 2001 4 % !d date Mon Feb 8 12:30:09 PST 2001 5 % dare dare: Command not found. 6 % ^r^t date Mon Feb 8 12:33:25 PST 2001
EXPLANATION
|
1 % cat file1 file2 file3 <Contents of files displayed here> % vi !:1 vi file1 2 % cat file1 file2 file3 <Contents of file, file2, and file3 are displayed here> % ls !:2 ls file2 file2 3 % cat file1 file2 file3 % ls !:3 ls file3 file3 4 % echo a b c a b c % echo !$ echo c c 5 % echo a b c a b c % echo !^ echo a a 6 % echo a b c a b c % echo !* echo a b c a b c 7 % !!:p echo a b c
EXPLANATION
|
An alias is a C shell user-defined abbreviation for a command. Aliases are useful when a command has a number of options and arguments or the syntax is difficult to remember. Aliases set at the command line are not inherited by subshells. Aliases are normally set in the .cshrc file. Since the .cshrc is executed when a new shell is started, any aliases set there will get reset for the new shell. Aliases may also be passed into shell scripts, but will cause potential portability problems unless they are directly set within the script.
Listing Aliases. The alias built-in command lists all set aliases. The alias is printed first, followed by the real command or commands it represents.
% alias co compress cp cp i ls1 enscript B r Porange f Courier8 !* & mailq /usr/lib/sendmail bp mroe more mv mv i rn /usr/spool/news/bin/rn3 uc uncompress uu uudecode vg vgrind t s11 !:1 | lpr t weekly (cd /home/jody/ellie/activity; ./weekly_report; echo Done)
EXPLANATIONThe alias command lists the alias (nickname) for the command in the first column and the real command the alias represents in the second column. |
Creating Aliases. The alias command is used to create an alias. The first argument is the name of the alias, the nickname for the command. The rest of the line consists of the command or commands that will be executed when the alias is executed. Multiple commands are separated by a semicolon, and commands containing spaces and metacharacters are surrounded by single quotes.
1 % alias m more 2 % alias mroe more 3 % alias lF 'ls -alF' 4 % alias cd 'cd \!*; set prompt = "$cwd >"' % cd .. /home/jody > cd / # New prompt displayed / >
EXPLANATION
|
Deleting Aliases. The unalias command is used to delete an alias. To temporarily turn off an alias, the alias name is preceded by a backslash.
1 % unalias mroe 2 % \cd ..
EXPLANATION
|
Alias Loop. An alias loop occurs when an alias definition references another alias that references back to the original alias.
1 % alias m more 2 % alias mroe m 3 % alias m mroe # Causes a loop 4 % m datafile Alias loop.
EXPLANATION
|
Job control is a powerful feature of the C shell that allows you to run programs, called jobs, in the background or foreground. Normally, a command typed at the command line runs in the foreground, and will continue until it has finished. If you have windows, job control may not be necessary, since you can simply open another window to start a new task. On the other hand, with a single terminal, job control is a very useful feature. For a list of job commands, see Table 9.1.
Command | Meaning |
---|---|
jobs | Lists all the jobs running. |
^Z (Control-Z) | Stops (suspends) the job; the prompt appears on the screen. |
bg | Starts running the stopped job in the background. |
fg | Brings a background job to the foreground. |
kill | Sends the kill signal to a specified job. |
The Ampersand and Background Jobs. If you expect a command to take a long time to complete, you can append the command with an ampersand and the job will execute in the background. The C shell prompt returns immediately and now you can type another command. Now the two commands are running concurrently, one in the background and one in the foreground. They both send their standard output to the screen. If you place a job in the background, it is a good idea to redirect its output either to a file or pipe it to a device such as a printer.
1 % find . -name core -exec rm {} \; & 2 [1] 543 3 %
EXPLANATION
|
The Suspend Key Sequence and Background Jobs. To suspend a program, the suspend key sequence, ^Z, is issued. The job is now suspended (stopped), the shell prompt is displayed, and the program will not resume until the fg or bg commands are issued. (When using the vi editor, the ZZ command writes and saves a file. Do not confuse this with ^Z, which would suspend the vi session.) If you try to log out when a job is suspended, the message There are stopped jobs appears on the screen.
The jobs Command. The C shell built-in command, jobs, displays the programs that are currently active and either running or suspended in the background. Running means the job is executing in the background. When a job is stopped, it is suspended; it is not in execution. In both cases, the terminal is free to accept other commands.
(The Command Line) 1 % jobs 2 [1] + Stopped vi filex [2] - Running sleep 25 3 % jobs -l [1] + 355 Stopped vi filex [2] - 356 Running sleep 25 4 [2] Done sleep 25
EXPLANATION
|
The Foreground and Background Commands. The fg command brings a background job into the foreground. The bg command starts a suspended job running in the background. A percent sign and the number of a job can be used as arguments to fg and bg if you want to select a particular job for job control.
1 % jobs 2 [1] + Stopped vi filex [2] - Running cc prog.c -o prog 3 % fg %1 vi filex (vi session starts) 4 % kill %2 [2] Terminated cc prog.c -o prog 5 % sleep 15 (Press ^z) Stopped 6 % bg [1] sleep 15 & [1] Done sleep 15
EXPLANATION
|
Metacharacters are special characters that are used to represent something other than themselves. As a rule of thumb, characters that are neither letters nor numbers may be metacharacters. The shell has its own set of metacharacters, often called shell wildcards. Shell metacharacters can be used to group commands together, to abbreviate filenames and pathnames, to redirect and pipe input/output, to place commands in the background, and so forth. Table 9.2 presents a partial list of shell metacharacters.
Metacharacter | Purpose | Example | Meaning |
---|---|---|---|
$ | Variable substitution | set name=Tom echo $name Tom | Sets the variable name to Tom; displays the value stored there. |
! | History substitution | !3 | Reexecutes the third event from the history list. |
* | Filename substitution | rm * | Removes all files. |
? | Filename substitution | ls ?? | Lists all two-character files. |
[ ] | Filename substitution | cat f[123] | Displays contents of f1, f2, f3. |
; | Command separator | ls;date;pwd | Each command is executed in turn. |
& | Background processing | lp mbox& | Printing is done in the background. Prompt returns immediately. |
> | Redirection of output | ls > file | Redirects standard output to file. |
< | Redirection of input | ls < file | Redirects standard input from file. |
>& | Redirection of output and error | ls >& file | Redirects both output and errors to file. |
>! | If noclobber is set, override it | ls >! file | If file exists, truncate and overwrite it, even if noclobber is set. |
>>! | If noclobber is set, override it | ls >>! file | If file does not exist, create it; even if noclobber is set. |
( ) | Groups commands to be executed in a subshell | (ls ; pwd) >tmp | Executes commands and sends output to tmp file. |
{ } | Groups commands to be executed in this shell | { cd /; echo $cwd } | Changes to root directory and displays current working directory. |
Filename Substitution. When evaluating the command line, the shell uses metacharacters to abbreviate filenames or pathnames that match a certain set of characters. The filename substitution metacharacters listed in Table 9.3 are expanded into an alphabetically listed set of filenames. The process of expanding a metacharacter into filenames is also called globbing. Unlike the other shells, when the C shell cannot substitute a filename for the metacharacter it is supposed to represent, the shell reports No match.
Metacharacter | Meaning |
---|---|
* | Matches zero or more characters. |
? | Matches exactly one character. |
[abc] | Matches one character in the set: a, b, or c. |
[a z] | Matches one character in the range a to z. |
{a, ile,ax} | Matches for a character or set of characters. |
~ | Substitutes the user's home directory for tilde. |
\ | Escapes or disables the metacharacter. |
The shell performs filename substitution by evaluating its metacharacters and replacing them with the appropriate letters or digits in a filename.
The Asterisk. The asterisk matches zero or more characters in a filename.
1 % ls a.c b.c abc ab3 file1 file2 file3 file4 file5 2 % echo * a.c b.c abc ab3 file1 file2 file3 file4 file5 3 % ls *.c a.c b.c 4 % rm z*p No match.
EXPLANATION
|
The Question Mark. The question mark matches exactly one character in a filename.
1 % ls a.c b.c abc ab3 file1 file2 file3 file4 file5 2 % ls ??? abc ab3 3 % echo How are you? No match. 4 % echo How are you\? How are you?
EXPLANATION
|
The Square Brackets. The square brackets match a filename for one character from a set or range of characters.
1 % ls a.c b.c abc ab3 file1 file2 file3 file4 file5 file10 file11 file12 2 % ls file[123] file1 file2 file3 3 % ls [A-Za-z][a-z][1-5] ab3 4 % ls file1[0-2] file10 file11 file12
EXPLANATION
|
The Curly Braces. The curly braces ({})match for a character or string of characters in a filename.
1 % ls a.c b.c abc ab3 ab4 ab5 file1 file2 file3 file4 file5 foo faa fumble 2 % ls f{oo,aa,umble} foo faa fumble 3 % ls a{.c,c,b[3-5]} a.c ab3 ab4 ab5
EXPLANATION
|
Escaping Metacharacters. The backslash is used to escape the special meaning of a single character. The escaped character will represent itself.
1 % gotta light? No match. 2 % gotta light\? gotta: Command not found.
EXPLANATION
|
Tilde Expansion. The tilde character by itself expands to the full pathname of the user's home directory. When the tilde is prepended to a username, it expands to the full pathname of that user's home directory. When prepended to a path, it expands to the home directory and the rest of the pathname.
1 % echo ~ /home/jody/ellie 2 % cd ~/desktop/perlstuff % pwd /home/jody/ellie/desktop/perlstuff 3 % cd ~joe % pwd /home/bambi/joe
EXPLANATION
|
Filename Completion: The filec Variable. When running interactively, the C shell provides a shortcut method for typing a filename or username. The built-in filec variable, when set, is used for what is called filename completion. If you type the first few significant characters of a file in the current working directory and press the ESC key, the shell fills in the rest of the filename, provided that there are not a number of other files beginning with the same characters. If you type Control-D after the partial spelling of the file, the shell will print out a list of files that match those characters. The terminal beeps if there are multiple matches. If the list begins with a tilde, the shell attempts to expand that list to a username.
1 % set filec 2 % ls rum rumple rumplestilsken run2 3 % ls ru[ESC][5] # terminal beeps 4 % ls rum^D rum rumple rumplestilsken 5 % ls rump[ESC] rumple 6 % echo ~ell[ESC] /home/jody/ellie
EXPLANATION
|
Turning Off Metacharacters with noglob. If the noglob variable is set, filename substitution is turned off, meaning that all metacharacters represent themselves; they are not used as wildcards. This can be useful when searching for patterns in programs like grep, sed, or awk, which may contain metacharacters that the shell may try to expand.
1 % set noglob 2 % echo * ?? [] ~ * ?? [] ~
EXPLANATION
|
Normally, standard output (stdout) from a command goes to the screen, standard input (stdin) comes from the keyboard, and error messages (stderr) go to the screen. The shell allows you to use the special redirection metacharacters to redirect the input/output to or from a file. The redirection operators (<, >, >>, >&) are followed by a filename. This file is opened by the shell before the command on the left-hand side is executed.
Pipes, represented by a vertical bar (|) symbol, allow the output of one command to be sent to the input of another command. The command on the left-hand side of the pipe is called the writer because it writes to the pipe. The command on the right-hand side of the pipe is the reader because it reads from the pipe. See Table 9.4 for a list of redirection and pipe metacharacters.
Metacharacter | Meaning |
---|---|
command < file | Redirects input from file to command. |
command > file | Redirects output from command to file. |
command >& file | Redirects output and errors to file. |
command >> file | Redirects output of command and appends it to file. |
command >>& file | Redirects and appends output and errors of command to file. |
command << WORD | Redirects input from first WORD to terminating WORD to command. |
<input> | User input goes here. It will be treated as a doubly quoted string of text. |
WORD | WORD marks the termination of input to command. |
command | command | Pipes output of first command to input of second command. |
command |& command | Pipes output and errors of first command to input of second command. |
command >! file | If the noclobber variable is set, override its effects for this command and either open or overwrite file. |
command >>! file | Override noclobber variable; if file does not exist, it is created and output from command is appended to it. |
command >>&! file | Override noclobber variable; if file does not exist, it is created and both output and errors are appended to it. |
Redirecting Input. Instead of the input coming from the terminal keyboard, it can be redirected from a file. The shell will open the file on the right-hand side of the < symbol and the program on the left will read from the file. If the file does not exist, the error No such file or directory will be reported by the C shell.
FORMATcommand < file |
mail bob < memo
EXPLANATIONThe file memo is opened by the shell, and the input is redirected to the mail program. Simply, the user bob is sent a file called memo by the mail program. |
The here document. The here document is another way to redirect input to a command. It is used in shell scripts for creating menus and processing input from other programs. Normally, programs that accept input from the keyboard are terminated with Control-D (^d). The here document provides an alternate way of sending input to a program and terminating the input without typing ^D. The << symbol is followed by a user-defined word, often called a terminator. Input will be directed to the command on the left-hand side of the << symbol until the user-defined terminator is reached. The final terminator is on a line by itself, and cannot be surrounded by any spaces. Variable and command substitution are performed within the here document. (Normally, here documents are used in shell scripts to create menus and provide input to commands such as mail, bc, ex, ftp, etc.)
FORMATcommand << MARK ... input ... MARK |
(Without the here document) (The Command Line) 1 % cat 2 Hello There. How are you? I'm tired of this. 3 ^D (The Output) 4 Hello There. How are you? I'm tired of this.
EXPLANATION
|
(With the here document) (The Command Line) 1 % cat << DONE 2 Hello There. How are you? I'm tired of this. 3 DONE (The Output) 4 Hello There. How are you? I'm tired of this.
EXPLANATION
|
(The Command Line) 1 % set name = steve 2 % mail $name << EOF 3 Hello there, $name 4 The hour is now 'date +%H' 5 EOF
EXPLANATION
|
Redirecting Output. By default, the standard output of a command or commands normally goes to the terminal screen. To redirect standard output from the screen to a file, the > symbol is used. The command is on the left-hand side of the > symbol, and a filename is on the right-hand side. The shell will open the file on the right-hand side of the > symbol. If the file does not exist, the shell will create it; if it does exist, the shell will open the file and truncate it. Often files are inadvertently removed when using redirection. (A special C shell variable, called noclobber, can be set to prevent redirection from clobbering an existing file. See Table 9.5.)
FORMATcommand > file |
cat file1 file2 > file3
EXPLANATIONThe contents of file1 and file2 are concatenated and the output is sent to file3. Remember that the shell opens file3 before it attempts to execute the cat command. If file3 already exists and contains data, the data will be lost. If file3 does not exist, it will be created. |
Appending Output to an Existing File. To append output to an existing file, the >> symbol is used. If the file on the right-hand side of the >> symbol does not exist, it is created; if it does exist, the file is opened and output is appended to the end of the file.
FORMATcommand >> file |
date >> outfile
EXPLANATIONThe standard output of the date command is redirected and appended to outfile. |
Redirecting Output and Error. The >& symbol is used to redirect both standard output and standard error to a file. Normally, a command is either successful and sends its output to stdout, or fails and sends its error messages to stderr. Some recursive programs, such as find and du, send both standard output and errors to the screen as they move through the directory tree. By using the >& symbol, both standard output and standard error can be saved in a file and examined. The C shell does not provide a symbol for redirection of only standard error, but it is possible to get just the standard error by executing the command in a subshell. See Figure 9.2.
1 % date Tue Aug 3 10:31:56 PDT 2001 2 % date >& outfile 3 % cat outfile Tue Aug 3 10:31:56 PDT 2001
EXPLANATION
|
1 % cp file1 file2 2 % cp file1 Usage: cp [-ip] f1 f2; or: cp [-ipr] f1 ... fn d2 3 % cp file1 >& errorfile 4 % cat errorfile Usage: cp [-ip] f1 f2; or: cp [-ipr] f1 ... fn d2
EXPLANATION
|
Separating Output and Errors. Standard output and standard error can be separated by enclosing the command in parentheses. When a command is enclosed in parentheses, the C shell starts up a subshell, handles redirection from within the subshell, and then executes the command. By using the technique shown in Example 9.43, the standard output can be separated from the errors.
(The Command Line) 1 % find . -name ' * .c' -print >& outputfile 2 % (find . -name '*.c' -print > goodstuff) >& badstuff
EXPLANATION
|
The noclobber Variable. The special C shell built-in variable noclobber, when set, protects you from clobbering files with redirection. See Table 9.5.
noclobber Is Not Set | File Exists | File Does Not Exist |
---|---|---|
command > file | file is overwritten. | file is created. |
command >> file | file is appended to. | file is created. |
noclobber Is Set | ||
command > file | Error message. | file is created. |
command >> file | file is appended to. | Error message. |
Overwriting noclobber | ||
command >! file | If the noclobber variable is set, override its effects for this command and either open or truncate file, redirecting output of command to file. | |
command >>! file | Override noclobber variable; if file does not exist, it is created and output from command is appended to it. (See Example 9.44.) |
1 % cat filex abc 123 2 % date > filex 3 % cat filex Wed Aug 5 11:51:04 PDT 2001 4 % set noclobber 5 % date > filex filex: File exists. 6 % ls >! filex # Override noclobber for this command only % cat filex abc ab1 dir filex plan.c 7 % ls > filex filex: File exists. 8 % unset noclobber # Turn off noclobber permanently
EXPLANATION
|
C shell variables hold only strings or a set of strings. Some variables are built into the shell and can be set by turning them on or off, such as the noclobber or filec variable. Others are assigned a string value, such as the path variable. You can create your own variables and assign them to strings or the output of commands. Variable names are case-sensitive and may contain up to 20 characters consisting of numbers, letters, and the underscore.
There are two types of variables: local and environment. The scope of a variable is its visibility. A local variable is visible to the shell where it is defined. The scope of environment variables is often called global. Their scope is for this shell and all processes spawned (started) from this shell.
The dollar sign ($) is a special metacharacter that, when preceding a variable name, tells the shell to extract the value of that variable. The echo command, when given the variable as an argument, will display the value of the variable after the shell has processed the command line and performed variable substitution.
The special notation $?, when prepended to the variable name, lets you know whether the variable has been set. If a one is returned, it means true, the variable has been set. If a zero is returned, it means false, the variable has not been set.
1 % set filec 2 % set history = 50 3 % set name = George 4 % set machine = 'uname -n' 5 % echo $?machine 1 6 % echo $?blah 0
EXPLANATION
|
Curly Braces. Curly braces insulate a variable from any characters that may follow it.
1 % set var = net % echo $var net 2 % echo $varwork varwork: Undefined variable. 3 % echo ${var}work network
EXPLANATION
|
Local Variables. Local variables are known only in the shell where they were created. If a local variable is set in the .cshrc file, the variable will be reset every time a new C shell is started. By convention, local variables are named with lowercase letters.
Setting Local Variables. If the string being assigned contains more than one word, it must be quoted; otherwise, only the first word will be assigned to the variable. It does not matter if there are spaces around the equal sign, but if there is a space on one side of the equal sign, there must be one on the other side.
1 % set round = world 2 % set name = "Santa Claus" 3 % echo $round world 4 % echo $name Santa Claus 5 % csh # Start a subshell 6 % echo $name name: Undefined variable.
EXPLANATION
|
The set Command. The set command prints all local variables set for this shell.
(The Command Line) % set argv () cwd /home/jody/ellie fignore .o filec history 500 home /home/jody/ellie hostname jody ignoreeof noclobber notify path (/home/jody/ellie /bin /usr/local /usr/usr/bin/usr/etc .) prompt jody% shell /bin/csh status 0 term sun cmd user ellie
EXPLANATIONAll of the local variables set for this shell are printed. Most of these variables are set in the cshrc file. The argv, cwd, shell, term, user, and status variables are preset, built-in variables. |
Built-In Local Variables. The shell has a number of predefined variables with their own definitions. Some of the variables are either on or off. For example, if you set noclobber, the variable is on and effective, and when you unset noclobber, it is turned off. Some variables require a definition when set. Built-in variables are usually set in the .cshrc file if they are to be effective for different C shells. Some of the built-in variables already discussed include noclobber, cdpath, history, filec, and noglob. For a complete list, see Table 9.16.
Environment Variables. Environment variables are often called global variables. They are defined in the shell where they were created and inherited by all shells spawned from that shell. Although environment variables are inherited by subshells, those defined in subshells are not passed back to parent shells. Inheritance is from parent to child, not the other way around (like real life). By convention, environment variables are named with capital letters.
(The Command Line) 1 % setenv TERM wyse 2 % setenv PERSON "Joe Jr." 3 % echo $TERM wyse 4 % echo $PERSON Joe Jr. 5 % echo $$ # $$ evaluates to the PID of the current shell 206 6 % csh # Start a subshell 7 % echo $$ 211 8 % echo $PERSON Joe Jr. 9 % setenv PERSON "Nelly Nerd" 10 % echo $PERSON % Nelly Nerd 11 % exit # Exit the subshell 12 % echo $$ 206 13 % echo $PERSON # Back in parent shell Joe Jr.
EXPLANATION
|
Printing Environment Variables. The printenv (UCB) and env (SVR4) commands print all the environment variables set for this shell and its subshells. The setenv command prints variables and their values on both the UCB and SVR4 versions of the C shell.
% env FONTPATH=/usr/local/OW3/lib/fonts HELPPATH=/usr/local/OW3/lib/locale:/usr/local/OW3/lib/help HOME=/home/jody/ellie LD_LIBRARY_PATH=/usr/local/OW3/lib LOGNAME=ellie MANPATH=/ur/local/man:/usr/local/man:/usr/local/doctools/man:/usr/man NOSUNVIEW=0 OPENWINHOME=/usr/local/OW3 PATH=/bin:/usr/local:/usr:/usr/bin:/usr/etc:/home/5bin:/usr/ doctools:/usr:. PWD=/home/jody/ellie SHELL=/bin/csh TERM=sun cmd USER=ellie WINDOW_PARENT=/dev/win0 WINDOW_TTYPARMS= WMGR_ENV_PLACEHOLDER=/dev/win3
EXPLANATIONThe environment variables are set for this session and all processes that are started from this shell. Many applications require the setting of environment variables. For example, the man command has a MANPATH variable set to the location that man pages can be found, and the openwin program has an environment variable set to the place where its fonts are stored. When any of these programs are executed, the information in these variables is passed to them. |
Arrays. In the C shell, an array is simply a list of words, separated by spaces or tabs, and enclosed in parentheses. The elements of the array are numbered by subscripts starting at one. If there is not an array element for a subscript, the message Subscript out of range is displayed. Command substitution will also create an array. If the $# notation precedes an array name, the number of elements in the array is displayed.
1 % set fruit = ( apples pears peaches plums ) 2 % echo $fruit apples pears peaches plums 3 % echo $fruit[1] # Subscripts start at 1 apples 4 % echo $fruit[2 4] # Prints the 2nd, 3rd, and 4th elements pears peaches plums 5 $ echo $fruit[6] Subscript out of range. 6 % echo $fruit[*] # Prints all elements of the array apples pears peaches plums 7 % echo $#fruit # Prints the number of elements 4 8 % echo $fruit[$#fruit] # Prints the last element plums 9 % set fruit[2] = bananas # Reassigns the second element % echo $fruit apples bananas peaches plums 10 % set path = ( ~ /usr/bin /usr /usr/local/bin . ) % echo $path /home/jody/ellie /usr/bin /usr /usr/local/bin . 11 % echo $path[1] /home/jody/ellie
EXPLANATION
|
The shift Command and Arrays. If the built-in shift command takes an array name as its argument, it shifts off (to the left) the first element of the array. The length of the array is decreased by one. (Without an argument, the shift command shifts off the first element of the built-in argv array. See "Command Line Arguments")
1 % set names = ( Mark Tom Liz Dan Jody ) 2 % echo $names Mark Tom Liz Dan Jody 3 % echo $names[1] Mark 4 % shift names 5 % echo $names Tom Liz Dan Jody 6 % echo $names[1] Tom 7 % set days = ( Monday Tuesday ) 8 % shift days 9 % echo $days Tuesday 10 % shift days 11 % echo $days 12 % shift days shift: no more words.
EXPLANATION
|
Creating an Array from a String. You may want to create a wordlist out of a quoted string. This is accomplished by placing the string variable within a set of parentheses.
1 % set name = "Thomas Ben Savage" % echo $name[1] Thomas Ben Savage 2 % echo $name[2] Subscript out of range. 3 % set name = ( $name ) 4 % echo $name[1] $name[2] $name[3] Thomas Ben Savage
EXPLANATION
|
Built into the C shell are several variables consisting of one character. The $ preceding the character allows variable interpretation. See Table 9.6.
Variable | Example | Meaning |
---|---|---|
$?var | echo $?name | Returns 1 if variable has been set, 0 if not. |
$#var | echo $#fruit | Prints the number of elements in an array. |
$$ | echo $$ | Prints the PID of the current shell. |
$< | set name = $< | Accepts a line of input from user up to newline. |
1 % set num % echo $?num 1 2 % echo $path /home/jody/ellie /usr/bin/ usr/local/bin % echo $#path 3 3 % echo $$ 245 % csh # Start a subshell % echo $$ 248 4 % set name = $< Christy Campbell % echo $name Christy Campbell
EXPLANATION
|
Pathname Variable Modifiers. If a pathname is assigned to a variable, it is possible to manipulate the pathname variable by appending special C shell extensions to it. The pathname is divided into four parts: head, tail, root, and extension. See Table 9.7 for examples of pathname modifiers and what they do.
Modifier | Meaning | Example | Result |
---|---|---|---|
:r | root | echo $pn:r | /home/ellie/prog/check |
:h | head | echo $pn:h | /home/ellie/prog |
:t | tail | echo $pn:t | check.c |
:e | extension | echo $pn:e | c |
:g | global | echo $p:gt | (See Example 9.55) |
1 % set pathvar = /home/danny/program.c 2 % echo $pathvar:r /home/danny/program 3 % echo $pathvar:h /home/danny 4 % echo $pathvar:t program.c 5 % echo $pathvar:e c 6 % set pathvar = ( /home/* ) echo $pathvar /home/jody /home/local /home/lost+found /home/perl /home/tmp 7 % echo $pathvar:gt jody local lost+found perl tmp
EXPLANATION
|
A string or variable can be assigned the output of a UNIX command by placing the command in backquotes. This is called command substitution. (On the keyboard, the backquote is normally below the tilde character.) If the output of a command is assigned to a variable, it is stored as a wordlist (see "Arrays" on page 370), not a string, so that each of the words in the list can be accessed separately. To access a word from the list, a subscript is appended to the variable name. Subscripts start at one.
1 % echo The name of my machine is 'uname -n'. The name of my machine is stardust. 2 % echo The present working directory is 'pwd'. The present working directory is /home/stardust/john. 3 % set d = 'date' % echo $d Sat Jun 20 14:24:21 PDT 2001 4 % echo $d[2] $d[6] Jun 2001 5 % set d = "'date'" % echo $d[1] Sat Jun 20 14:24:21 PDT 2001
EXPLANATION
|
Wordlists and Command Substitution. When a command is enclosed in backquotes and assigned to a variable, the resulting value is an array (wordlist). Each element of the array can be accessed by appending a subscript to the array name. The subscripts start at one. If a subscript that is greater than the number of words in the array is used, the C shell prints Subscript out of range. If the output of a command consists of more than one line, the newlines are stripped from each line and replaced with a single space.
1 % set d = 'date' % echo $d Fri Aug 29 14:04:49 PDT 2001 3 % echo $d[1 3] Fri Aug 29 4 % echo $d[6] 2001 4 % echo $d[7] Subscript out of range. 5 % echo The calendar for the month of November is 'cal 11 2001'" The calendar for month of November is November 2001 S M Tu W Th F S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
EXPLANATION
|
1 % set machine = 'rusers | awk '/tom/{print $1}'' 2 % echo $machine dumbo bambi dolphin 3 % echo $#machine 3 4 % echo $machine[$#machine] dolphin 5 % echo $machine dumbo bambi dolphin 6 % shift $machine % echo $machine bambi dolphin 7 % echo $machine[1] bambi 8 % echo $#machine 2
EXPLANATION
|
The C shell has a whole set of metacharacters that have some special meaning. In fact, almost any character on your keyboard that is not a letter or a number has some special meaning for the shell. Here is a partial list:
* ? [ ] $ ~ ! ^ & { } ( ) > < | ; : %
The backslash and quotes are used to escape the interpretation of metacharacters by the shell. Whereas the backslash is used to escape a single character, the quotes can be used to protect a string of characters. There are some general rules for using quotes:
Quotes are paired and must be matched on a line. The backslash character can be used to escape a newline so that a quote can be matched on the next line.
Single quotes will protect double quotes, and double quotes will protect single quotes.
Single quotes protect all metacharacters from interpretation, with the exception of the history character (!).
Double quotes protect all metacharacters from interpretation, with the exception of the history character (!), the variable substitution character ($), and the backquotes (used for command substitution).
The Backslash. The backslash is used to escape the interpretation of a single character and, in the C shell, is the only character that can be used to escape the history character, the exclamation point (also called the bang). Often the backslash is used to escape the newline character. Backslash interpretation does not take place within quotes.
1 % echo Who are you? echo: No match. 2 % echo Who are you\? Who are you? 3 % echo This is a very,very long line and this is where I\ break the line. This is a very, very long line and this is where I I break the line. 4 % echo "\\abc" \\abc % echo '\\abc' \\abc % echo \\abc \abc
EXPLANATION
|
Single Quotes. Single quotes must be matched on the same line and will escape all metacharacters with the exception of the history (bang) character (!). The history character is not protected because the C shell evaluates history before it does quotes, but not before backslashes.
1 % echo 'I need $5.00' I need $5.00 2 % echo 'I need $500.00 now\!\!' I need $500.00 now!! 3 % echo 'This is going to be a long line so Unmatched '. 4 % echo 'This is going to be a long line so \ I used the backslash to suppress the newline' This is going to be a long line so I used the backslash to suppress the newline
EXPLANATION
|
Double Quotes. Double quotes must be matched, will allow variable and command substitution, and hide everything else except the history (bang) character (!). The backslash will not escape the dollar sign when enclosed in double quotes.
1 % set name = Bob % echo "Hi $name" Hi Bob 2 % echo "I don't have time." I don't have time. 3 % echo "WOW!" # Watch the history metacharacter! ": Event not found. 4 % echo "Whoopie\!" Whoopie! 5 % echo "I need \$5.00" I need \.00
EXPLANATION
|
The Quoting Game. As long as the quoting rules are adhered to, double quotes and single quotes can be used in a variety of combinations in a single command.
1 % set name = Tom 2 % echo "I can't give $name" ' $5.00\!' I can't give Tom $5.00! 3 % echo She cried, \"Oh help me\!' "', $name. She cried, "Oh help me!", Tom.
EXPLANATION
|
Steps to Successful Quoting. In a more complex command, it is often difficult to match quotes properly unless you follow the steps listed here. (See Appendix C.)
Know the UNIX command and its syntax. Before variable substitution, hard code the values into the command line to see if you get the expected results.
% nawk -F: '/^Zippy Pinhead/{print "Phone is " $2}' datafile 408-123-4563
If the UNIX command worked correctly, then plug in the variables. At this point, do not remove or change any quotes. Simply put the variables in place of the words they represent. In this example, replace Zippy Pinhead with $name.
% set name = "Zippy Pinhead" % nawk -F: '/^$name/{print "Phone is " $2}' datafile
Play the quoting game as follows: Starting at the left-hand side with the first single quote, insert a matching single quote just before the dollar sign in $name. Now you have a set of matched quotes.
nawk -F: '/^'$name/{print "Phone is " $2}' datafile
Now, right after the last letter, e in $name, place another single quote. (Believe me, this works.) This quote matches the quote after the closing curly brace.
% nawk -F: '/^'$name'/{print "Phone is " $2}' datafile
Count the number of single quotes, starting at the left-hand side. You have four, a nice even number. Everything within each set of single quotes is ignored by the shell. The quotes are matched as follows:
Last step: Double quote the variables. Surround each variable very snugly within a set of double quotes. The double quotes protect the whitespace in the expanded variable; for example, the space in Zippy Pinhead is protected.
Quoting Variables. The :x and :q modifiers are used when it is necessary to quote variables.
Quoting with the :q Modifier. The :q modifier is used to replace double quotes.
1 % set name = "Daniel Savage" 2 % grep $name:q database same as 3 % grep "$name" database 4 % set food = "apple pie" 5 % set dessert = ( $food "ice cream") 6 % echo $#dessert 3 7 % echo $dessert[1] apple 8 % echo $dessert[2] pie 9 % echo $dessert[3] ice cream 10 % set dessert = ($food:q "ice cream") 11 % echo $#dessert 2 12 % echo $dessert[1] apple pie 13 % echo $dessert[2] ice cream
EXPLANATION
|
Quoting with the :x Modifier. If you are creating an array and any of the words in the list contain metacharacters, :x prevents the shell from interpreting the metacharacters when performing variable substitution
1 % set things = "*.c a?? file[1 5]" % echo $#things 1 2 % set newthings = ( $things ) set: No match. 3 % set newthings = ( $things:x ) 4 % echo $#newthings 3 5 % echo "$newthings[1] $newthings[2] $newthings[3] " *.c a?? file[1-5] 6 % grep $newthings[2]:q filex The question marks in a?? would be used for filename expansion it is not quoted
EXPLANATION
|
A shell script is normally written in an editor and consists of commands interspersed with comments. Comments are preceded by a pound sign and consist of text used to document what is going on.
The First Line. At the top left corner, the line preceded by #! (often called shbang) indicates the program that will be executing the lines in the script. This line is commonly
#!/bin/csh
The #!, also called a magic number, is used by the kernel to identify the program that should be interpreting the lines in the script. When a program is loaded into memory, the kernel will examine the first line. If the first line is binary data, the program will be executed as a compiled program; if the first line contains the #!, the kernel will look at the path following the #! and start that program as the interpreter. If the path is /bin/csh, the C shell will interpret the lines in the program. This line must be the top line of your script or the line will be treated as a comment line.
When the script starts, the .cshrc file is read first and executed, so that anything set within that file will become part of your script. You can prevent the .cshrc from being read into your script by using the f (fast) option to the C shell program. This option is written as
#!/bin/csh -f
Comments. Comments are lines preceded by a pound sign (#). They are used to document your script. It is sometimes difficult to understand what the script is supposed to do if it is not commented. Although comments are important, they are often too sparse or not even used at all. Try to get used to commenting what you are doing not only for someone else, but also for yourself. Two days from now you may not remember exactly what you were trying to do.
Making the Script Executable. When you create a file, it is not given execute permission. You need this permission to run your script. Use the chmod command to turn on execute permission.
1 % chmod +x myscript 2 % ls -lF myscript -rwxr--xr--x 1 ellie 0 Jul 13:00 myscript*
EXPLANATION
|
An Example Scripting Session. In the following example, the user will create the script in the editor. After saving the file, the execute permissions are turned on with the chmod command, and the script is executed. If there are errors in the program, the C shell will respond immediately.
(The Script - info) #!/bin/csh -f # This script is called info 1 echo Hello ${LOGNAME}! 2 echo The hour is 'date +%H' 3 echo "This machine is 'uname -n'" 4 echo The calendar for this month is 5 cal 6 echo The processes you are running are: 7 ps -ef | grep "^ *$LOGNAME" 8 echo "Thanks for coming. See you soon\!\!" (The Command Line) % chmod +x info % info 1 Hello ellie! 2 The hour is 09 3 This machine is jody 4 The calendar for this month is 5 July 2001 S M Tu W Th F S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 7 The processes you are running are: < output of ps prints here > 8 Thanks for coming. See you soon!!
EXPLANATION
|
The $< Variable. To make a script interactive, a special C shell variable is used to read standard input into a variable. The $< symbol reads a line from standard input up to but not including the newline, and assigns the line to a variable[6].
(The Script - greeting) #/bin/csh -f # The greeting script 1 echo -n "What is your name? " 2 set name = $< 3 echo Greetings to you, $name. (The Command Line) % chmod +x greeting % greeting 1 What is your name? Dan Savage 3 Greetings to you, Dan Savage.
EXPLANATION
|
Creating a Wordlist from the Input String. Since the input from the $< variable is stored as a string, you may want to break the string into a wordlist.
1 % echo What is your full name\? 2 % set name = $< Lola Justin Lue 3 % echo Hi $name[1] Hi Lola Justin Lue 4 % echo $name[2] Subscript out of range. 5 % set name = ( $name ) 6 % echo Hi $name[1] Hi Lola 7 % echo $name[2] $name[3] Justin Lue
EXPLANATION
|
There is not really a need to do math problems in a shell script, but sometimes arithmetic is necessary, e.g., to increment or decrement a loop counter. The C shell supports integer arithmetic only. The @ symbol is used to assign the results of calculations to numeric variables.
Arithmetic Operators. The following operators in Table 9.8 are used to perform integer arithmetic operations. They are the same operators as found in the C programming language. See Table 9.13 for operator precedence. Also borrowed from the C language are shortcut assignment operators, shown in Table 9.9.
Function | Operator |
---|---|
Addition | + |
Subtraction | - |
Division | / |
Multiplication | * |
Modulus | % |
Left shift | << |
Right shift | >> |
Operator | Example | Equivalent to |
---|---|---|
+= | @ num += 2 | @ num = $num + 2 |
-= | @ num -= 4 | @ num = $num - 4 |
*= | @ num *= 3 | @ num = $num * 3 |
/= | @ num /= 2 | @ num = $num / 2 |
++ | @ num++ | @ num = $num + 1 |
- - | @ num- - | @ num = $num - 1 |
1 % @ sum = 4 + 6 echo $sum 10 2 % @ sum++ echo $sum 11 3 % @ sum += 3 echo $sum 14 4 % @ sum-- echo $sum 13 5 % @ n = 3+4 @: Badly formed number
EXPLANATION
|
Floating Point Arithmetic. Since floating point arithmetic is not supported by this shell, if you should need more complex mathematical operations, you can use UNIX utilities.
The bc and nawk utilities are useful if you need to perform complex calculations.
(The Command Line) 1 set n='echo "scale=3; 13 / 2" | bc' echo $n 6.500 2 set product='nawk -v x=2.45 -v y=3.124 'BEGIN{\ printf "%.2f\n", x * y }'' % echo $product 7.65
EXPLANATION
|
C shell scripts often fail because of some simple syntax error or logic error. Options to the csh command are provided to help you debug your programs. See Table 9.10.
As options to csh | |
---|---|
csh x scriptname | Display each line of script after variable substitution and before execution. |
csh v scriptname | Display each line of script before execution, just as you typed it. |
csh n scriptname | Interpret but do not execute commands. |
As arguments to the set command | |
set echo | Display each line of script after variable substitution and before execution. |
set verbose | Display each line of script before execution, just as you typed it. |
As the first line in a script | |
#!/bin/csh xv | Turns on both echo and verbose. These options can be invoked separately or combined with other csh invocation arguments. |
(The -v and -x Options) 1 % cat practice #!/bin/csh echo Hello $LOGNAME echo The date is 'date' echo Your home shell is $SHELL echo Good-bye $LOGNAME 2 % csh -v practice echo Hello $LOGNAME Hello ellie echo The date is 'date' The date is Sun May 23 12:24:07 PDT 2001 echo Your login shell is $SHELL Your login shell is /bin/csh echo Good-bye $LOGNAME Good-bye ellie 3 % csh -x practice echo Hello ellie Hello ellie echo The date is 'date' date The date is Sun May 23 12:24:15 PDT 2001 echo Your login shell is /bin/csh Your login shell is /bin/csh echo Good-bye ellie Good-bye ellie
EXPLANATION
|
(Echo and Verbose) 1 % cat practice #!/bin/csh echo Hello $LOGNAME echo The date is 'date' set echo echo Your home shell is $SHELL unset echo echo Good-bye $LOGNAME % chmod +x practice 2 % practice Hello ellie The date is Sun May 26 12:25:16 PDT 2001 --> echo Your login shell is /bin/csh --> Your login shell is /bin/csh --> unset echo Good-bye ellie
EXPLANATION
|
1 % cat practice #!/bin/csh echo Hello $LOGNAME echo The date is 'date' set verbose echo Your home shell is $SHELL unset verbose echo Good-bye $LOGNAME 2 % practice Hello ellie The date is Sun May 23 12:30:09 PDT 2001 --> echo Your login shell is $SHELL --> Your login shell is /bin/csh --> unset verbose Good-bye ellie
EXPLANATION
|
Shell scripts can take command line arguments. Arguments are used to modify the behavior of the program in some way. The C shell assigns command line arguments to positional parameters and enforces no specific limit on the number of arguments that can be assigned (the Bourne shell sets a limit of nine positional parameters). Positional parameters are number variables. The scriptname is assigned to $0, and any words following the scriptname are assigned to $1, $2, $3 ${10}, ${11}, and so on. $1 is the first command line argument. In addition to using positional parameters, the C shell provides the argv built-in array.
Positional Parameters and argv. If using the argv array notation, a valid subscript must be provided to correspond to the argument being passed in from the command line or the error message Subscript out of range is sent by the C shell. The argv array does not include the scriptname. The first argument is $argv[1], and the number of arguments is represented by $#argv. (There is no other way to represent the number of arguments.) See Table 9.11 for a list of command line arguments.
Argument | Meaning |
---|---|
$0 | The name of the script. |
$1, $2, ${10} | The first and second positional parameters are referenced by the number preceded by a dollar sign. The curly braces shield the number 10 so that it does not print the first positional parameter followed by a zero. |
$* | All the positional parameters. |
$argv[0] | Not valid; nothing is printed. C shell array subscripts start at 1. |
$argv[1] $argv[2] | The first argument, second argument, etc. |
$argv[*] | All arguments. |
$argv | All arguments. |
$#argv | The number of arguments. |
$argv[$#argv] | The last argument. |
(The Script) #!/bin/csh f # The greetings script # This script greets a user whose name is typed in at the # command line. 1 echo $0 to you $1 $2 $3 2 echo Welcome to this day 'date | awk '{print $1, $2, $3}'' 3 echo Hope you have a nice day, $argv[1]\! 4 echo Good bye $argv[1] $argv[2] $argv[3] (The Command Line) % chmod +x greetings % greetings Guy Quigley 1 greetings to you Guy Quigley 2 Welcome to this day Fri Aug 28 3 Hope you have a nice day, Guy! 4 Subscript out of range
EXPLANATION
|
When making decisions, the if, if/else, if/else if, and switch commands are used. These commands control the flow of the program by allowing decision-making based on whether an expression is true or false.
Testing Expressions. An expression consists of a set of operands separated by operators. Operators and precedence are listed in Tables 9.12 and 9.13. To test an expression, the expression is surrounded by parentheses. The C shell evaluates the expression, resulting in either a zero or nonzero numeric value. If the result is nonzero, the expression is true; if the result is zero, the expression is false.
Operator | Meaning | Example |
---|---|---|
== | Is equal to | $x == $y |
!= | Is not equal to | $x != $y |
> | Is greater than | $x > $y |
>= | Is greater than or equal to | $x >= $y |
< | Is less than | $x < $y |
<= | Is less than or equal to | $x <= $y |
=~ | String matches | $ans =~ [Yy]* |
!~ | String does not match | $ans !~ [Yy]* |
! | Logical not | ! $x |
|| | Logical or | $x || $y |
&& | Logical and | $x && $y |
When evaluating an expression with the logical and (&&), the shell evaluates from left to right. If the first expression (before the &&) is false, the shell assigns false as the result of the entire expression, never checking the remaining expressions. If the first expression is false, the whole expression is false when using the logical and (&&) operator. Both expressions surrounding a logical && operator must be true for the entire expression to evaluate to true.
When evaluating an expression with the logical or (||), if the first expression to the left of the || is true, the shell assigns true to the entire expression and never checks further. In a logical || expression, only one of the expressions must be true.
The logical not is a unary operator; that is, it evaluates one expression. If the expression to the right of the not operator is true, the expression becomes false. If it is false, the expression becomes true.
Precedence and Associativity. Like C, the C shell uses precedence and associativity rules when testing expressions. If you have an expression with a mix of different operators, such as the following:
@ x = 5 + 3 * 2 echo $x 11
the shell reads the operators in a certain order. Precedence refers to the order of importance of the operator. Associativity refers to whether the shell reads the expression from left to right or right to left when the precedence is equal.[7] Other than in arithmetic expressions (which you will not readily need in shell scripts anyway), the order of associativity is from left to right if the precedence is equal. You can change the order by using parentheses. (See Table 9.13.)
@ x = ( 5 + 3 ) * 2 echo $x 16
Expressions can be numeric, relational, or logical. Numeric expressions use the following arithmetic operators:
+ * / ++ -- %
Relational expressions use the operators that yield either a true (nonzero) or false (zero) result:
> < >= <= == !=
Logical expressions use these operators:
! && ||
Precedence | Operator | Meaning |
---|---|---|
High | ( ) | Change precedence; group |
~ | Complement | |
! | Logical not, negation | |
* / % | Multiply, divide, modulo | |
+ - | Add, subtract | |
<< >> | Bitwise left and right shift | |
> >= < <= | Relational operators: greater than, less than | |
== != | Equality: equal to, not equal to | |
=~ !~ | Pattern matching: matches, does not match | |
& | Bitwise and | |
^ | Bitwise exclusive or | |
| | Bitwise inclusive or | |
&& | Logical and | |
Low | || | Logical or |
The if Statement. The simplest form of conditional is the if statement. After the if is tested, and if the expression evaluates to true, the commands after the then keyword are executed until the endif is reached. The endif keyword terminates the block. The if statement may be nested as long as every single if statement is terminated with a matching endif. The endif goes with the nearest enclosing if.
FORMATif ( expression ) then command command endif |
(In the Script: Checking for Arguments) 1 if ( $#argv != 1 ) then 2 echo "$0 requires an argument" 3 exit 1 4 endif
EXPLANATION
|
Testing and Unset or Null Variables. The $? special variable is used to test if a variable has been set. It will return true if the variable is set to null.
(From .cshrc File) if ( $?prompt ) then set history = 32 endif
EXPLANATIONThe .cshrc file is executed every time you start a new csh program. $? is used to check to see if a variable has been set. In this example, the shell checks to see if the prompt has been set. If the prompt is set, you are running an interactive shell, not a script. The prompt is only set for interactive use. Since the history mechanism is only useful when running interactively, the shell will not set history if you are running a script. |
(The Script) echo -n "What is your name? " 1 set name = $< 2 if ( "$name" != "" ) then grep "$name" datafile endif
EXPLANATION
|
The if/else Statements. The if/else construct is a two-way branching control structure. If the expression after the if command is true, the block following it is executed; otherwise, the block after the else is executed. The endif matches the innermost if statement and terminates the statement.
FORMATif ( expression ) then command else command endif |
1 if ( $answer =~ [Yy]* ) then 2 mail bob < message 3 else 4 mail john < datafile 5 endif
EXPLANATION
|
Debugging Expressions. The x option (called echoing) to the C shell allows you to trace what is going on in your script as it executes. If you are unsure what is going on, this is a good way to debug your script.
(The Script: Using Logical Expressions and Checking Values) #!/bin/csh -f # Scriptname: logical set x = 1 set y = 2 set z = 3 1 if ( ( "$x" && "$y" ) || ! "$z" ) then # Note: grouping and parentheses 2 echo TRUE else echo FALSE endif (The Output) 3 % csh -x logical set x = 1 set y = 2 set z = 3 if ( ( 1 && 2 ) || ! 3 ) then echo TRUE TRUE else %
EXPLANATION
|
The if Statement and a Single Command. If an expression is followed by a single command, the then and endif keywords are not necessary.
FORMATif ( expression ) single command |
if ($#argv == 0) exit 1
EXPLANATIONThe expression is tested. If the number of command line arguments, $#argv, is equal to zero, the program is exited with a status of one. |
The if/else if Statements. The if/else if construct offers a multiway decision-making mechanism. A number of expressions can be tested, and when one of the expressions evaluated is true, the block of statements that follow is executed. If none of the expressions are true, the else block is executed.
FORMATif ( expression ) then command command else if ( expression ) then command command else command endif |
(The Script: grade) #!/bin/csh -f # This script is called grade echo -n "What was your grade? " set grade = $< 1 if ( $grade >= 90 && $grade <= 100 ) then echo "You got an A\!" 2 else if ( $grade > 79 ) then echo "You got a B" 3 else if ( $grade > 69 ) then echo "You're average" else 4 echo "Better study" 5 endif
EXPLANATION
|
Exit Status and the Status Variable. Every UNIX command returns an exit status. If the command was successful, it returns an exit status of zero. If the command failed, it returns a nonzero exit status. You can test to see whether the command succeeded or failed by looking at the value of the C shell status variable. The status variable contains the exit status of the last command executed.
1 % grep ellie /etc/passwd ellie:pHAZk66gA:9496:41:Ellie:/home/jody/ellie:/bin/csh 2 % echo $status 0 # Zero shows that grep was a success 3 % grep joe /etc/passwd 4 % echo $status 1 # Nonzero shows that grep failed
EXPLANATION
|
Exiting from a Shell Script. In your shell script, the exit command will take you back to the shell prompt. The exit command takes an integer value to indicate the type of exit. A nonzero argument indicates failure; zero indicates success. The number must be between 0 and 255.
EXPLANATION
|
Using the Status Variable in a Script. The status variable can be used in a script to test the status of a command. The status variable is assigned the value of the last command that was executed.
(The Script) #!/bin/csh -f 1 ypmatch $1 passwd >& /dev/null 2 if ( $status == 0 ) then 3 echo Found $1 in the NIS database endif
EXPLANATION
|
Evaluating Commands within Conditionals. The C shell evaluates expressions in conditionals. To evaluate commands in conditionals, curly braces must enclose the command. If the command is successful, that is, returns an exit status of zero, the curly braces tell the shell to evaluate the expression as true (1).[8] If the command fails, the exit status is nonzero, and the expression is evaluated as false (0).
It is important, when using a command in a conditional, to know the exit status of that command. For example, the grep program returns an exit status of zero when it finds the pattern it is searching for, one when it cannot find the pattern, and two when it cannot find the file. When awk or sed are searching for patterns, those programs return zero whether or not they are successful in the pattern search. The criterion for success with awk and sed is based on whether or not the syntax is right; that is, if you typed the command correctly, the exit status of awk and sed is zero.
If the exclamation mark is placed before the expression, it nots the entire expression so that if true, it is now false, and vice versa. Make sure a space follows the exclamation mark, or the C shell will invoke the history mechanism.
FORMATif { ( command ) } then command command endif |
#!/bin/csh -f 1 if { ( who | grep $1 >& /dev/null ) } then 2 echo $1 is logged on and running: 3 ps -ef | grep "^ *$1" # ps aux for BSD 4 endif
EXPLANATION
|
FORMATif ! { (command) } then |
1 if ! { ( ypmatch $user passwd >& /dev/null ) } then 2 echo $user is not a user here. exit 1 3 endif
EXPLANATION
|
The goto. A goto allows you to jump to some label in the program and start execution at that point. Although gotos are frowned upon by many programmers, they are sometimes useful for breaking out of nested loops.
(The Script) #!/bin/csh -f 1 startover: 2 echo "What was your grade? " set grade = $< 3 if ( "$grade" < 0 || "$grade" > 100 ) then 4 echo "Illegal grade" 5 goto startover endif if ( $grade >= 89 ) then echo "A for the genius\!" else if ( $grade >= 79 ) then .. < Program continues >
EXPLANATION
|
File Testing. The C shell has a built-in set of options for testing attributes of files, such as, Is it a directory, a plain file (not a directory), or a readable file, and so forth. For other types of file tests, the UNIX test command is used. The built-in options for file inquiry are listed in Table 9.14.
Test Flag | (What It Tests) True If |
---|---|
r | Current user can read the file. |
w | Current user can write to the file. |
x | Current user can execute the file. |
e | File exists. |
o | Current user owns the file. |
z | File is zero length. |
d | File is a directory. |
f | File is a plain file. |
#!/bin/csh -f 1 if ( e file ) then echo file exists endif 2 if ( d file ) then echo file is a directory endif 3 if ( ! z file ) then echo file is not of zero length endif 4 if ( -r file && -w file ) then echo file is readable and writeable endif
EXPLANATION
|
The test Command and File Testing. The UNIX test command includes options that were built-in to the C shell, as well as a number of options that were not. See Table 9.15 for a list of test options. You may need these additional options when testing less common attributes of files such as block and special character files, or setuid files. The test command evaluates an expression and returns an exit status of either zero for success or one for failure. When using the test command in an if conditional statement, curly braces must surround the command so that the shell can evaluate the exit status properly.[9]
To use the test command in a conditional statement, use curly braces as you would for any other command for the C shell to evaluate the exit status properly.
Option | Meaning Tests True If |
---|---|
b | File is a block special file. |
c | File is a character special file. |
d | File exists and is a directory file. |
f | File exists and is a plain file. |
g | File has the set-group-ID bit set. |
k | File has the sticky bit set. |
p | File is a named pipe. |
r | Current user can read the file. |
s | File exists and is not empty. |
t n | n is file descriptor for terminal. |
u | File has the set-user-ID bit set. |
w | Current user can write to the file. |
x | Current user can execute the file. |
1 if { test b file } echo file is a block device file 2 if { test u file } echo file has the set user id bit set
EXPLANATION
|
Nesting Conditionals. Conditional statements can be nested. Every if must have a corresponding endif (else if does not have an endif). It is a good idea to indent nested statements and line up the ifs and endifs so that you can read and test the program more effectively.
EXPLANATION
|
The switch Command. The switch command is an alternative to using the if then else if construct. Sometimes the switch command makes a program clearer to read when handling multiple options. The value in the switch expression is matched against the expressions, called labels, following the case keyword. The case labels will accept constant expressions and wildcards. The label is terminated with a colon. The default label is optional, but its action is taken if none of the other cases match the switch expression. The breaksw is used to transfer execution to the endsw. If a breaksw is omitted and a label is matched, any statements below the matched label are executed until either a breaksw or endsw is reached.
FORMATswitch (variable) case constant: commands breaksw case constant: commands breaksw endsw |
(The Script - colors) #!/bin/csh -f # This script is called colors 1 echo -n "Which color do you like? " 2 set color = $< 3 switch ("$color") 4 case bl*: echo I feel $color echo The sky is $color 5 breaksw 6 case red: # Is is red or is it yellow? 7 case yellow: 8 echo The sun is sometimes $color. 9 breaksw 10 default: 11 echo $color not one of the categories. 12 breaksw 13 endsw (The Command Line) % colors (The Output) 1 Which color do you like? red 8 The sun is sometimes red. 1 Which color do you like? Doesn't matter 11 Doesn't matter is not one of the categories.
EXPLANATION
|
Nesting Switches. Switches can be nested; i.e., a switch statement and its cases can be contained within another switch statement as one of its cases. There must be an endsw to terminate each switch statement. A default case is not required.
(The Script: systype) #!/bin/csh -f # This script is called systype # Program to determine the type of system you are on. echo "Your system type is: " 1 set release = ('uname -r') 2 switch ('uname -s') 3 case SunOS: 4 switch ("$release") 5 case 4.*: echo "SunOS $release" breaksw 6 case [56].*: echo "Solaris $release" breaksw 7 endsw breaksw case HP*: echo HP-UX breaksw case Linux: echo Linux breaksw 8 endsw (The Command Line) % systype Your system type: SunOS 4.1.2
EXPLANATION
|
Looping constructs allow you to execute the same statements a number of times. The C shell supports two types of loops: the foreach loop and the while loop. The foreach loop is used when you need to execute commands on a list of items, one item at a time, such as a list of files or a list of usernames. The while loop is used when you want to keep executing a command until a certain condition is met.
The foreach Loop. The foreach command is followed by a variable and a wordlist enclosed in parentheses. The first time the loop is entered, the first word in the list is assigned to the variable. The list is shifted to the left by one and the body of the loop is entered. Each command in the loop body is executed until the end statement is reached. Control returns to the top of the loop. The next word on the list is assigned to the variable, the commands after the foreach line are executed, the end is reached, control returns to the top of the foreach loop, the next word in the wordlist is processed, and so on. When the wordlist is empty, the loop ends.
FORMATforeach variable (wordlist) commands end |
1 foreach person (bob sam sue fred) 2 mail $person < letter 3 end
EXPLANATION
|
(The Command Line) % cat maillist tom dick harry dan (The Script - mailtomaillist) #!/bin/csh -f # This script is called mailtomaillist 1 foreach person ('cat maillist') 2 mail $person <<EOF Hi $person, How are you? I've missed you. Come on over to my place. Your pal, $LOGNAME@'uname n' EOF 3 end
EXPLANATION
|
1 foreach file (*.c) 2 cc $file -o $file:r end
EXPLANATION
|
(The Command Line) 1 % runit f1 f2 f3 dir2 dir3 (The Script) #!/bin/csh -f # This script is called runit. # It loops through a list of files passed as # arguments. 2 foreach arg ($*) 3 if ( e $arg ) then ... Program code continues here else ... Program code continues here endif 4 end 5 echo "Program continues here"
EXPLANATION
|
The while Loop. The while loop evaluates an expression, and as long as the expression is true (nonzero), the commands below the while command will be executed until the end statement is reached. Control will then return to the while expression, the expression will be evaluated, and if still true, the commands will be executed again, and so on. When the while expression is false, the loop ends and control starts after the end statement.
(The Script) #!/bin/csh -f 1 set num = 0 2 while ($num < 10) 3 echo $num 4 @ num++ # See arithmetic. 5 end 6 echo "Program continues here"
EXPLANATION
|
(The Script) #!/bin/csh -f 1 echo n "Who wrote \"War and Peace\"?" 2 set answer = $< 3 while ("$answer" != "Tolstoy") echo "Wrong, try again\!" 4 set answer = $< 5 end 6 echo Yeah!
EXPLANATION
|
The repeat Command. The repeat command takes two arguments, a number and a command. The command is executed that number of times.
% repeat 3 echo hello hello hello hello
EXPLANATIONThe echo command is executed three times. |
The shift Command. The shift command, without an array name as its argument, shifts the argv array by one word from the left, thereby decreasing the size of the argv array by one. Once shifted off, the array element is lost.
(The Script) #!/bin/csh -f # Script is called loop.args 1 while ($#argv) 2 echo $argv 3 shift 4 end (The Command Line) 5 % loop.args a b c d e a b c d e b c d e c d e d e e
EXPLANATION
|
The break Command. The break command is used to break out of a loop so that control starts after the end statement. It breaks out of the innermost loop. Execution continues after the end statement of the loop.
EXPLANATION
|
#!/bin/csh -f # This script is called database 1 while (1) echo "Select a menu item" 2 cat << EOF 1) Append 2) Delete 3) Update 4) Exit EOF 3 set choice = $< 4 switch ($choice) case 1: echo "Appending" 5 break # Break out of loop; not a breaksw case 2: echo "Deleting" break case 3: echo "Updating" break case 4: exit 0 default: 6 echo "Invalid choice. Try again. endsw 7 end 8 echo "Program continues here"
EXPLANATION
|
Nested Loops and the repeat Command. Rather than a goto, the repeat command can be used to break out of nested loops. The repeat command will not do this with the continue command.
(The Output) Hello, in 1st loop In 2nd loop In 3rd loop Out of all loops
EXPLANATION
|
The continue Command. The continue statement starts execution at the top of the innermost loop.
EXPLANATION
|
EXPLANATION
|
If a script is interrupted with the Interrupt key, it terminates and control is returned to the C shell, that is, you get your prompt back. The onintr command is used to process interrupts within a script. It allows you to ignore the interrupt (^C) or transfer control to another part of the program before exiting. Normally, the interrupt command is used with a label to "clean up" before exiting. The onintr command without arguments restores the default action.
(The Script) 1 onintr finish 2 < Script continues here > 3 finish: 4 onintr # Disable further interrupts 5 echo Cleaning temp files 6 rm $$tmp* ; exit 1
EXPLANATION
|
Whoever runs a setuid program temporarily (as long as he or she is running the setuid program) becomes the owner of that program and has the same permissions as the owner. The passwd program is a good example of a setuid program. When you change your password, you temporarily become root, but only during the execution of the passwd program. That is why you are able to change your password in the /etc/passwd (or /etc/shadow) file, which normally is off-limits to regular users.
Shell programs can be written as setuid programs. You might want to do this if you have a script that is accessing a file containing information that should not be accessible to regular users, such as salary or personal information. If the script is a setuid script, the person running the script can have access to the data, but it is still restricted from others. A setuid program requires the following steps:
In the script, the first line is
#!/bin/csh feb The feb options: f fast start up; don't execute .cshrc e abort immediately if interrupted b this is a setuid script
Next, change the permissions on the script so that it can run as a setuid program:
% chmod 4755 script_name or % chmod +srx script_name % ls l rwsr xr x 2 ellie 512 Oct 10 17:18 script_name
After creating successful scripts, it is customary to collect them in a common script directory and change your path so that the scripts can be executed from any location.
1 % mkdir ~/bin 2 % mv myscript ~/bin 3 % vi .login In .login reset the path to add ~/bin. 4 set path = ( /usr/ucb /usr /usr/etc ~/bin . ) 5 (At command line) % source .login
EXPLANATION
|
Rather than residing on disk like UNIX commands, built-in commands are part of the C shell's internal code and are executed from within the shell. If a built-in command occurs as any component of a pipeline except the last, it is executed in a subshell. See Table 9.16 for a list of built-in commands.
Built-In Command | Meaning |
---|---|
: | Interpret null command, but perform no action. |
alias | A nickname for a command. |
bg [%job] | Run the current or specified jobs in the background. |
break | Break out of the innermost foreach or while loop. |
breaksw | Break from a switch, resuming after the endsw. |
case label: | A label in a switch statement. |
cd [dir] chdir [dir] | Change the shell's working directory to dir. If no argument is given, change to the home directory of the user. |
continue | Continue execution of the nearest enclosing while or foreach. |
default: | Label the default case in a switch statement. The default should come after all case labels. |
dirs [ l] | Print the directory stack, most recent to the left; the first directory shown is the current directory. With the l argument, produce an unabbreviated printout; use of the ~ notation is suppressed. |
echo [ n] list | Write the words in list to the shell's standard output, separated by space characters. The output is terminated with a newline unless the n option is used. |
eval command | Run command as standard input to the shell and execute the resulting commands. This is usually used to execute commands generated as the result of command or variable substitution, since parsing occurs before these substitutions (e.g., eval 'tset -s options'). |
exec command | Execute command in place of the current shell, which terminates. |
exit [(expr)] | Exit the shell, either with the value of the status variable or with the value specified by expr. |
fg [% job] | Bring the current or specified job into the foreground. |
foreach var (wordlist) | See "The foreach Loop" on page 412. |
glob wordlist | Perform filename expansion on wordlist. Like echo, but no escapes (\) are recognized. Words are delimited by null characters in the output. |
goto label | See "The goto" on page 405. |
hashstat | Print a statistics line indicating how effective the internal hash table has been at locating commands (and avoiding execs). An exec is attempted for each component of the path where the hash function indicates a possible hit, and in each component that does not begin with a backslash. |
history [ hr] [n] | Display the history list; if n is given, display only the n most recent events. |
r | Reverse the order of the printout to be most recent first rather than oldest first. |
h | Display the history list without leading numbers. This is used to produce files suitable for sourcing using the h option to source. |
if (expr) | See "Flow Control and Conditional Constructs". |
else if (expr2) then | See "Flow Control and Conditional Constructs". |
jobs [ l] | List the active jobs under job control. |
l | List IDs in addition to the normal information. |
kill [ sig] [pid] [%job] kill l | Send the TERM (terminate) signal, by default or by the signal specified, to the specified ID, the job indicated, or the current job. Signals are given either by number or name. There is no default. Typing kill does not send a signal to the current job. If the signal being sent is TERM (terminate) or HUP (hangup), then the job or process is sent a CONT (continue) signal as well. |
l | List the signal names that can be sent. |
limit [ h] [resource max use]] | Limit the consumption by the current process or any process it spawns, each not to exceed max use on the specified resource. If max use is omitted, print the current limit; if resource is omitted, display all limits. |
h | Use hard limits instead of the current limits. Hard limits impose a ceiling on the values of the current limits. Only the superuser may raise the hard limits. Resource is one of: cputime, maximum CPU seconds per process; filesize, largest single file allowed; datasize, maximum data size (including stack) for the process; stacksize, maximum stack size for the process; coredump, maximum size of a core dump; and descriptors, maximum value for a file descriptor. |
login [username| p] | Terminate a login shell and invoke login(1). The .logout file is not processed. If username is omitted, login prompts for the name of a user. |
p | Preserve the current environment (variables). |
logout | Terminate a login shell. |
nice [+n| n] command] | Increment the process priority value for the shell or command by n. The higher the priority value, the lower the priority of a process and the slower it runs. If command is omitted, nice increments the value for the current shell. If no increment is specified, nice sets the nice value to 4. The range of nice values is from 20 through 19. Values of n outside this range set the value to the lower or higher boundary, respectively. |
+n | Increment the process priority value by n. |
n | Decrement by n. This argument can be used only by the superuser. |
nohup [command] | Run command with HUPs (hangups) ignored. With no arguments, ignore HUPs throughout the remainder of a script. |
notify [%job] | Notify the user asynchronously when the status of the current or of a specified job changes. |
onintr [ | label] | Control the action of the shell on interrupts. With no arguments, onintr restores the default action of the shell on interrupts. (The shell terminates shell scripts and returns to the terminal command input level.) With the minus sign argument, the shell ignores all interrupts. With a label argument, the shell executes a goto label when an interrupt is received or a child process terminates because it was interrupted. |
popd [+n] | Pop the directory stack and cd to the new top directory. The elements of the directory stack are numbered from zero, starting at the top. |
+n | Discard the nth entry in the stack. |
pushd [+n | dir] | Push a directory onto the directory stack. With no arguments, exchange the top two elements. |
+n | Rotate the nth entry to the top of the stack and cd to it. |
dir | Push the current working directory onto the stack and change to dir. |
rehash | Recompute the internal hash table of the contents of directories listed in the path variable to account for new commands added. |
repeat count command | Repeat command count times. |
set [var [= value]] | See "Variables". |
setenv [VAR [word]] | See "Variables". The most commonly used environment variables, USER, TERM, and PATH, are automatically imported to and exported from the csh variables, user, term, and path; there is no need to use setenv for these. In addition, the shell sets the PWD environment variable from the csh variable cwd whenever the latter changes. |
shift [variable] | The components of argv, or variable, if supplied, are shifted to the left, discarding the first component. It is an error for variable not to be set, or to have a null value. |
source [ h] name | Read commands from name. Source commands may be nested, but if they are nested too deeply, the shell may run out of file descriptors. An error in a sourced file at any level terminates all nested source commands. Used commonly to reexecute the .login or .cshrc files to ensure variable settings are handled within the current shell, i.e., shell does not create a child shell (fork). Place commands from the filename on the history list without executing them. |
h | |
stop [%job] | Stop the current or specified background job. |
suspend | Stop the shell in its tracks, much as if it had been sent a stop signal with ^Z. This is most often used to stop shells started by su. |
switch (string) | See "The switch Command" on page 409. |
time [command] | With no argument, print a summary of time used by this C shell and its children. With an optional command, execute command and print a summary of the time it uses. |
umask [value] | Display the file creation mask. With value, set the file creation mask. Value, given in octal, is xored with the permissions of 666 for files and 777 for directories to arrive at the permissions for new files. Permissions cannot be added via umask. |
unalias pattern | Discard aliases that match (filename substitution) pattern. All aliases are removed by unalias.* |
unhash | Disable the internal hash table. |
unlimit [ h] [resource] | Remove a limitation on resource. If no resource is specified, all resource limitations are removed. See the description of the limit command for the list of resource names. |
h | Remove corresponding hard limits. Only the superuser may do this. |
unset pattern | Remove variables whose names match (filename substitution) pattern. All variables are removed by 'unset *'; this has noticeably distasteful side effects. |
unsetenv variable | Remove variable from the environment. Pattern matching, as with unset, is not performed. |
wait | Wait for background jobs to finish (or for an interrupt) before prompting. |
while (expr) | See "The while Loop" on page 415. |
%[job] [&] | Bring the current or indicated job to the foreground. With the ampersand, continue running job in the background. |
@ [var =expr] @ [var[n] =expr] | With no arguments, display the values for all shell variables. With arguments, the variable var, or the nth word in the value of var, is set to the value that expr evaluates to. |
1: | What does the init process do? |
2: | What is the function of the login process? |
3: | How do you know what shell you are using? |
4: | How can you change your login shell? |
5: | Explain the difference between the .cshrc and .login files. Which one is executed first? |
6: | Edit your .cshrc file as follows:
Set the following variables and put a comment after each variable explaining what it does: noclobber # Protects clobbering files from redirection overwriting history ignoreeof savehist filec |
7: | Type the following: source .cshrc What does the source command do? |
8: | Edit your .login file as follows:
|
9: | Type history. What is the output?
Use the history command to reexecute the echo command with only its last argument, c. |
1: | Type at the prompt: touch ab abc a1 a2 a3 all a12 ba ba.1 ba.2 filex filey AbC ABC ABc2 abc |
2: | Write and test the command that will do the following:
|
1: | What are the names of the three file streams associated with your terminal? |
2: | What is a file descriptor? |
3: | What command would you use to do the following:
|
4: | What happens when you type cp all by itself?
|
5: | Use the find command to find all files, starting from the parent directory, and of type directory. Save the standard output in a file called found and any errors in a file called found.errs. |
6: | What is noclobber? How do you override it? |
7: | Take the output of three commands and redirect the output to a file called gotemail. |
8: | Use a pipe(s) with the ps and wc commands to find out how many processes you are currently running. |
1: | Write a script called greetme that will do the following:
|
2: | Make sure your script is executable. chmod +x greetme |
3: | What was the first line of your script? |
1: | Write a script called nosy that will do the following:
The output should resemble the following:
|
2: | Create a text file called datafile (unless this file has already been provided for you.) Each entry consists of fields separated by colons. The fields are:
|
3: | Create a script called lookup that will do the following:
|
4: | Try the echo and verbose commands for debugging your script. How did you use these commands? |
1: | Write a script called rename that will do the following:
|
2: | Write a script called checking that will do the following:
|
1: | In the lookup script, ask the user if he or she would like to add an entry to the datafile. If yes or y:
|
2: | Rewrite checking.
|
3: | The lookup script depends on the datafile in order to run. In the lookup script, check to see if the datafile exists and if it is readable and writeable. |
4: | Add a menu to the lookup script to resemble the following:
|
5: | You already have the Add entry part of the script written. The Add entry routine should now include code that will check to see if the name is already in the datafile and if it is, tell the user so. If the name is not there, add the new entry. |
6: | Now write the code for the Delete entry, View entry, and Exit functions. |
7: | The Delete part of the script should first check to see if the entry exists before trying to remove it. If the entry does not exist, notify the user; otherwise, remove the entry and tell the user you removed it. On exit, make sure that you use a digit to represent the appropriate exit status. |
8: | How do you check the exit status from the command line? |
1: | Rewrite the following script using a switch statement. #!/bin/csh f # Grades program echo n "What was your grade on the test? " set score = $< if ( $grade >= 90 && $grade <= 100 ) then echo You got an A\! else if ( $grade >= 80 && $grade < 89 ) then echo You got a B. else if ( $grade >= 79 && $grade < 79 ) then echo "You're average." else if ( $grade >= 69 && $grade < 69 ) then echo Better study harder else echo Better luck next time. endif |
2: | Rewrite the lookup script using switch statements for each of the menu items. |
1: | Write a program called picnic that will mail a list of users, one at a time, an invitation to a picnic. The list of users will be in a file called friends. One of the users listed in the friends file will be Popeye.
Bonus: If you have time, you may want to customize yourinvite file so that each user receives a letter containing his or her name. For example, the message might start:
To do this your invite file may be written:
With sed or awk, you could then substitute XXX with the user name. (It might be tricky putting the capital letter in the user name, since user names are always lowercase.) |
2: | Add a new menu item to the lookup script to resemble the following:
After the user has selected a valid entry, when the function has completed, ask the user if he or she would like to see the menu again. If an invalid entry is entered, the program should print the following:
The menu will be redisplayed. |
3: | Create a submenu under View entry in the lookup script. The user will be asked if he would like to view specific information for a selected individual:
|
4: | Add the onintr command to your script using a label. When the program starts execution at the label, any temporary files will be removed, the user will be told Good bye, and the program will exit. |
[1] Do not confuse the search path variable with the cdpath variable set in the cshrc file.
[2] The length of the command line can be 256 characters or more; it can be even higher on different versions of UNIX.
[3] The find syntax requires a semicolon at the end of an exec statmemt. The semicolon is preceded by a backslash to prevent the shell from interpreting it.
[4] Programs such as grep, sed, and awk have a set of metacharacters, called regular expression metacharac-ters, for pattern matching. These should not be confused with shell metacharacters.
[5] [ESC] stands for Escape key.
[6] Another way to read one line of input is setvariable = 'head -1'.
[7] Associativity in arithmetic expressions is right to left in cases of equal precedence.
[8] The command's exit status is inverted by the shell so that the expression yields a true or false result.
[9] A common error is to name your script test. If your search path contains the UNIX test command first, itwill execute it. The test command either displays an error or nothing at all if the syntax is correct.
CONTENTS |