📄 assortedtips.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Assorted Tips</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Miscellany"HREF="miscellany.html"><LINKREL="PREVIOUS"TITLE="Optimizations"HREF="optimizations.html"><LINKREL="NEXT"TITLE="Security Issues"HREF="securityissues.html"><METAHTTP-EQUIV="Content-Style-Type"CONTENT="text/css"><LINKREL="stylesheet"HREF="common/kde-common.css"TYPE="text/css"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=iso-8859-1"><METAHTTP-EQUIV="Content-Language"CONTENT="en"><LINKREL="stylesheet"HREF="common/kde-localised.css"TYPE="text/css"TITLE="KDE-English"><LINKREL="stylesheet"HREF="common/kde-default.css"TYPE="text/css"TITLE="KDE-Default"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#AA0000"VLINK="#AA0055"ALINK="#AA0000"STYLE="font-family: sans-serif;"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="optimizations.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 33. Miscellany</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="securityissues.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="ASSORTEDTIPS"></A>33.8. Assorted Tips</H1><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN18867"></A>33.8.1. Ideas for more powerful scripts</H2><UL><LI><P><ANAME="PSEUDOCODEREF"></A></P><P>You have a problem that you want to solve by writing a Bash script. Unfortunately, you don't know quite where to start. One method is to plunge right in and code those parts of the script that come easily, and write the hard parts as <ICLASS="FIRSTTERM">pseudo-code</I>.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 ARGCOUNT=1 # Need name as argument. 4 E_WRONGARGS=65 5 6 if [ number-of-arguments is-not-equal-to "$ARGCOUNT" ] 7 # ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ 8 # Can't figure out how to code this . . . 9 #+ . . . so write it in pseudo-code. 10 11 then 12 echo "Usage: name-of-script name" 13 # ^^^^^^^^^^^^^^ More pseudo-code. 14 exit $E_WRONGARGS 15 fi 16 17 . . . 18 19 exit 0 20 21 22 # Later on, substitute working code for the pseudo-code. 23 24 # Line 6 becomes: 25 if [ $# -ne "$ARGCOUNT" ] 26 27 # Line 12 becomes: 28 echo "Usage: `basename $0` name"</PRE></TD></TR></TABLE></P><P>For an example of using pseudo-code, see the <AHREF="writingscripts.html#NEWTONSQRT">Square Root</A> exercise.</P></LI><LI><P><ANAME="TRACKINGSCR"></A></P><P>To keep a record of which user scripts have run during a particular session or over a number of sessions, add the following lines to each script you want to keep track of. This will keep a continuing file record of the script names and invocation times. </P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 # Append (>>) following to end of each script tracked. 2 3 whoami>> $SAVE_FILE # User invoking the script. 4 echo $0>> $SAVE_FILE # Script name. 5 date>> $SAVE_FILE # Date and time. 6 echo>> $SAVE_FILE # Blank line as separator. 7 8 # Of course, SAVE_FILE defined and exported as environmental variable in ~/.bashrc 9 #+ (something like ~/.scripts-run)</PRE></TD></TR></TABLE> </P></LI><LI><P><ANAME="PREPENDREF"></A></P><P>The <SPANCLASS="TOKEN">>></SPAN> operator <ICLASS="FIRSTTERM">appends</I> lines to a file. What if you wish to <ICLASS="FIRSTTERM">prepend</I> a line to an existing file, that is, to paste it in at the beginning?</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 file=data.txt 2 title="***This is the title line of data text file***" 3 4 echo $title | cat - $file >$file.new 5 # "cat -" concatenates stdout to $file. 6 # End result is 7 #+ to write a new file with $title appended at *beginning*.</PRE></TD></TR></TABLE> </P><P>This is a simplified variant of the <AHREF="here-docs.html#PREPENDEX">Example 18-13</A> script given earlier. And, of course, <AHREF="sedawk.html#SEDREF">sed</A> can also do this.</P></LI><LI><P><ANAME="SCRIPTASEMB"></A></P><P>A shell script may act as an embedded command inside another shell script, a <ICLASS="FIRSTTERM">Tcl</I> or <ICLASS="FIRSTTERM">wish</I> script, or even a <AHREF="filearchiv.html#MAKEFILEREF">Makefile</A>. It can be invoked as an external shell command in a C program using the <TTCLASS="REPLACEABLE"><I>system()</I></TT> call, i.e., <TTCLASS="REPLACEABLE"><I>system("script_name");</I></TT>.</P></LI><LI><P><ANAME="SETVAREMB"></A></P><P>Setting a variable to the contents of an embedded <ICLASS="FIRSTTERM">sed</I> or <ICLASS="FIRSTTERM">awk</I> script increases the readability of the surrounding <AHREF="wrapper.html#SHWRAPPER">shell wrapper</A>. See <AHREF="contributed-scripts.html#MAILFORMAT">Example A-1</A> and <AHREF="internal.html#COLTOTALER3">Example 14-20</A>.</P></LI><LI><P><ANAME="LIBROUTINES"></A></P><P>Put together files containing your favorite and most useful definitions and functions. As necessary, <SPANCLASS="QUOTE">"include"</SPAN> one or more of these <SPANCLASS="QUOTE">"library files"</SPAN> in scripts with either the <AHREF="special-chars.html#DOTREF">dot</A> (<BCLASS="COMMAND">.</B>) or <AHREF="internal.html#SOURCEREF">source</A> command.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 # SCRIPT LIBRARY 2 # ------ ------- 3 4 # Note: 5 # No "#!" here. 6 # No "live code" either. 7 8 9 # Useful variable definitions 10 11 ROOT_UID=0 # Root has $UID 0. 12 E_NOTROOT=101 # Not root user error. 13 MAXRETVAL=255 # Maximum (positive) return value of a function. 14 SUCCESS=0 15 FAILURE=-1 16 17 18 19 # Functions 20 21 Usage () # "Usage:" message. 22 { 23 if [ -z "$1" ] # No arg passed. 24 then 25 msg=filename 26 else 27 msg=$@ 28 fi 29 30 echo "Usage: `basename $0` "$msg"" 31 } 32 33 34 Check_if_root () # Check if root running script. 35 { # From "ex39.sh" example. 36 if [ "$UID" -ne "$ROOT_UID" ] 37 then 38 echo "Must be root to run this script." 39 exit $E_NOTROOT 40 fi 41 } 42 43 44 CreateTempfileName () # Creates a "unique" temp filename. 45 { # From "ex51.sh" example. 46 prefix=temp 47 suffix=`eval date +%s` 48 Tempfilename=$prefix.$suffix 49 } 50 51 52 isalpha2 () # Tests whether *entire string* is alphabetic. 53 { # From "isalpha.sh" example. 54 [ $# -eq 1 ] || return $FAILURE 55 56 case $1 in 57 *[!a-zA-Z]*|"") return $FAILURE;; 58 *) return $SUCCESS;; 59 esac # Thanks, S.C. 60 } 61 62 63 abs () # Absolute value. 64 { # Caution: Max return value = 255. 65 E_ARGERR=-999999 66 67 if [ -z "$1" ] # Need arg passed. 68 then 69 return $E_ARGERR # Obvious error value returned. 70 fi 71 72 if [ "$1" -ge 0 ] # If non-negative, 73 then # 74 absval=$1 # stays as-is. 75 else # Otherwise, 76 let "absval = (( 0 - $1 ))" # change sign. 77 fi 78 79 return $absval 80 } 81 82 83 tolower () # Converts string(s) passed as argument(s) 84 { #+ to lowercase. 85 86 if [ -z "$1" ] # If no argument(s) passed, 87 then #+ send error message 88 echo "(null)" #+ (C-style void-pointer error message) 89 return #+ and return from function. 90 fi 91 92 echo "$@" | tr A-Z a-z 93 # Translate all passed arguments ($@). 94 95 return 96 97 # Use command substitution to set a variable to function output. 98 # For example: 99 # oldvar="A seT of miXed-caSe LEtTerS" 100 # newvar=`tolower "$oldvar"` 101 # echo "$newvar" # a set of mixed-case letters 102 # 103 # Exercise: Rewrite this function to change lowercase passed argument(s) 104 # to uppercase ... toupper() [easy]. 105 }</PRE></TD></TR></TABLE> </P></LI><LI><P><ANAME="COMMENTH"></A></P><P>Use special-purpose comment headers to increase clarity and legibility in scripts.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 ## Caution. 2 rm -rf *.zzy ## The "-rf" options to "rm" are very dangerous, 3 ##+ especially with wild cards. 4 5 #+ Line continuation. 6 # This is line 1 7 #+ of a multi-line comment, 8 #+ and this is the final line. 9 10 #* Note. 11 12 #o List item. 13 14 #> Another point of view. 15 while [ "$var1" != "end" ] #> while test "$var1" != "end"</PRE></TD></TR></TABLE></P></LI><LI><P><ANAME="COMOUTBL"></A></P><P>A particularly clever use of <AHREF="tests.html#TESTCONSTRUCTS1">if-test</A> constructs is for comment blocks.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 COMMENT_BLOCK= 4 # Try setting the above variable to some value 5 #+ for an unpleasant surprise. 6 7 if [ $COMMENT_BLOCK ]; then 8 9 Comment block -- 10 ================================= 11 This is a comment line. 12 This is another comment line. 13 This is yet another comment line. 14 ================================= 15 16 echo "This will not echo." 17 18 Comment blocks are error-free! Whee! 19 20 fi 21 22 echo "No more comments, please." 23 24 exit 0</PRE></TD></TR></TABLE> </P><P>Compare this with <AHREF="here-docs.html#CBLOCK1">using here documents to comment out code blocks</A>.</P></LI><LI><P><ANAME="INTPARAM"></A></P><P>Using the <AHREF="variables2.html#XSTATVARREF">$? exit status variable</A>, a script may test if a parameter contains only digits, so it can be treated as an integer.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -