|
網誌存檔
熱門網志
|
|
|
How to write a shell script Creating a Script and you`d rather type a simple command, say Create a shell script Observations Should be located in your search path and ~/bin should be in your search path. From the man page for exec(2): You can get away without this, but you shouldn`t. All good scripts state the interpretor explicitly. Long ago there was just one (the Bourne Shell) but these days there are many interpretors -- Csh, Ksh, Bash, and others. Comments A PATH specification is recommended -- often times a script will fail for some people because they have a different or incomplete search path. Argument Checking if [ $# -ne 3 ]; then This script requires three arguments and gripes accordingly. Exit status if [ $year -lt 1901 -o $year -gt 2099 ]; then etc... # All done, exit ok exit 0 A non-zero exit status indicates an error condition of some sort while a zero exit status indicates things worked as expected. Using exit status if command; then For example, Your code should be written with the expectation that others will use it. Making sure you return a meaningful exit status will help. if [ $year -lt 1901 -o $year -gt 2099 ]; then etc... # ok, you have the number of days since Jan 1, ... case `expr $days % 7` in etc... Error messages should appear on stderr not on stdout! Output should appear on stdout. As for input/output dialogue: if tty -s ; then Note: this code behaves differently if there`s a user to communicate with (ie. if the standard input is a tty rather than a pipe, or file, or etc. See tty(1)). for variable in word ... For example: Alternatively you may see: Case case word in For example: case "$year" in [0-9][0-9]) Conditional Execution if command For example: Alternatively you may see: While/Until Iteration {while | until} command For example: while [ $# -ge 1 ]; do Alternatively you may see: Variables Numeric variables (eg. like $1, etc.) are positional vari- ables for argument communication.
PATH=/usr/ucb:/usr/bin:/bin; export PATH or Exporting Variables # We MUST have a DISPLAY environment variable if [ "$DISPLAY" = "" ]; then Likewise, for variables like the PRINTER which you want hon- ored by lpr(1). From a user`s .profile: Note: that the Cshell exports all environment variables. Referencing Variables # Most user`s have a /bin of their own if [ "$USER" != "root" ]; then The braces are required for concatenation constructs. The value of the variable "p_01". The value of the variable "p" with "_01" pasted onto the end. Conditional Reference ${variable-word} If the variable has been set, use it`s value, else use word. ${variable:-word} If the variable has been set and is not null, use it`s value, else use word. ${variable:?word} If variable is set use it`s value, else print out word and exit. Useful for bailing out. Arguments $0, $1, ... The command and arguments. With $0 the command and the rest the arguments. The number of arguments. All the arguments as a blank separated string. Watch out for "$*" vs. "$@". Shift the postional variables down one and decrement number of arguments. Set the positional variables to the argument list. # parse argument list while [ $# -ge 1 ]; do A use of the set command: TODAY=`(set \`date\`; echo $1)` cd $SPOOL for i in `cat $LOGS` Special Variables Current process id. This is very useful for constructing temporary files. $? The exit status of the last command. if [ $? -eq 0 ]
; & ( ) | ^ < > new-line space tab These are for command sequences, background jobs, etc. To quote any of these use a backslash (\) or bracket with quote marks ("" or ``). Within single quotes all characters are quoted -- including the backslash. The result is one word.
Double Quotes if [ ! "${parent}" ]; then Back Quotes
and Functions name () For example: # Purge a directory _purge() if [ ! -d $1 ]; then etc... Within a function the positional parmeters $0, $1, etc. are the arguments to the function (not the arguments to the script). Functions are good for encapsulations. You can pipe, redi- rect input, etc. to functions. For example: # deal with a file, add people one at a time do_file() etc... etc... # take standard input (or a specified file) and do it. if [ "$1" != "" ]; then Sourcing commands sh command This runs the shell script as a separate shell. For example, on Sun machines in /etc/rc: sh /etc/rc.local . command # Read in configuration information What are the virtues of each? What`s the difference? The second form is useful for configuration files where environment variable are set for the script. For example: # is there a config file for this host? if [ -r ${BACKUPHOME}/${HOST} ]; then Using configuration files in this manner makes it possible to write scripts that are automatically tailored for differ- ent situations. if test expression; then etc... and (note the matching bracket argument) etc... On System V machines this is a builtin (check out the com- mand /bin/test). Useful expressions are: test { -w, -r, -x, -s, ... } filename is file writeable, readable, executeable, empty, etc? are numbers equal, not equal, greater than, etc.? Are strings the same or different? Binary or; binary and; use ! for unary negation. if [ $year -lt 1901 -o $year -gt 2099 ]; then Learn this command inside out! It does a lot for you. String matching # parse argument list while [ $# -ge 1 ]; do shift done Of course getopt would work much better. SysV vs BSD echo echo -n Ok to procede?; read ans On SysV systems you`d say: In an effort to produce portable code we`ve been using: if [ "`echo -n`" = "-n" ]; then etc... echo $n Ok to procede? $c; read ans Is there a person? User prompts aren`t required if there`s no user. # If there`s a person out there, prod him a bit. if tty -s; then The tradition also extends to output. if tty -s <&1; then Beware: just because stdin is a tty that doesn`t mean that stdout is too. User prompts should be directed to the user terminal. if tty -s; then Have you ever had a program stop waiting for keyboard input when the output is directed elsewhere? Creating Input # take standard input (or a specified file) and do it. if [ "$1" != "" ]; then alternatively, redirection from a file: if [ "$1" != "" ]; then You can also construct files on the fly. subscribe $2 Usenet Feeder at UWO Note: that variables are expanded in the input. String Manipulations
TIME=`date | sed `s/.* .* .* \(.*\) .* .*/\1/`` TIME=`date | awk `{print $4}`` TIME=`set \`date\`; echo $4` TIME=`date | (read u v w x y z; echo $x)` With some care, redefining the input field separators can help. #!/bin/sh name() if [ $# -ne 1 ]; then add=`name $1` nslookup < < EOF | grep "$add" | sed `s/.*= //` Debugging sh -n command Read the shell script but don`t execute the commands. IE. check syntax. sh -x command Display commands and arguments as they`re executed. In a lot of my shell scripts you`ll see # Uncomment the next line for testing
|
-------------------------------------------------
| 上一篇:Exploring Mysql CURDATE and NOW. The same but different. | 下一篇:Linux user commands |

