⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debugging.html

📁 Shall高级编程
💻 HTML
📖 第 1 页 / 共 2 页
字号:
><B><ANAME="TRAPREF1"></A>Trapping signals</B></P><DL><DT><BCLASS="COMMAND">trap</B></DT><DD><P>Specifies an action on receipt of a signal; also	        useful for debugging.	      <DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P><ANAME="SIGNALD"></A>A		<ICLASS="FIRSTTERM">signal</I> is simply a message		sent to a process, either by the kernel or another		process, telling it to take some specified action		(usually to terminate).  For example, hitting a		<BCLASS="KEYCAP">Control</B>-<BCLASS="KEYCAP">C</B>,		sends a user interrupt, an INT signal, to a running		program.</P></TD></TR></TABLE></DIV>		<TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;trap '' 2   2&nbsp;# Ignore interrupt 2 (Control-C), with no action specified.    3&nbsp;   4&nbsp;trap 'echo "Control-C disabled."' 2   5&nbsp;# Message when Control-C pressed.</PRE></TD></TR></TABLE>	      </P></DD></DL></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="EX76"></A><P><B>Example 29-5. Trapping at exit</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# Hunting variables with a trap.   3&nbsp;   4&nbsp;trap 'echo Variable Listing --- a = $a  b = $b' EXIT   5&nbsp;#  EXIT is the name of the signal generated upon exit from a script.   6&nbsp;#   7&nbsp;#  The command specified by the "trap" doesn't execute until   8&nbsp;#+ the appropriate signal is sent.   9&nbsp;  10&nbsp;echo "This prints before the \"trap\" --"  11&nbsp;echo "even though the script sees the \"trap\" first."  12&nbsp;echo  13&nbsp;  14&nbsp;a=39  15&nbsp;  16&nbsp;b=36  17&nbsp;  18&nbsp;exit 0  19&nbsp;#  Note that commenting out the 'exit' command makes no difference,  20&nbsp;#+ since the script exits in any case after running out of commands.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="ONLINE"></A><P><B>Example 29-6. Cleaning up after <BCLASS="KEYCAP">Control-C</B></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# logon.sh: A quick 'n dirty script to check whether you are on-line yet.   3&nbsp;   4&nbsp;umask 177  # Make sure temp files are not world readable.   5&nbsp;   6&nbsp;   7&nbsp;TRUE=1   8&nbsp;LOGFILE=/var/log/messages   9&nbsp;#  Note that $LOGFILE must be readable  10&nbsp;#+ (as root, chmod 644 /var/log/messages).  11&nbsp;TEMPFILE=temp.$$  12&nbsp;#  Create a "unique" temp file name, using process id of the script.  13&nbsp;#     Using 'mktemp' is an alternative.  14&nbsp;#     For example:  15&nbsp;#     TEMPFILE=`mktemp temp.XXXXXX`  16&nbsp;KEYWORD=address  17&nbsp;#  At logon, the line "remote IP address xxx.xxx.xxx.xxx"  18&nbsp;#                      appended to /var/log/messages.  19&nbsp;ONLINE=22  20&nbsp;USER_INTERRUPT=13  21&nbsp;CHECK_LINES=100  22&nbsp;#  How many lines in log file to check.  23&nbsp;  24&nbsp;trap 'rm -f $TEMPFILE; exit $USER_INTERRUPT' TERM INT  25&nbsp;#  Cleans up the temp file if script interrupted by control-c.  26&nbsp;  27&nbsp;echo  28&nbsp;  29&nbsp;while [ $TRUE ]  #Endless loop.  30&nbsp;do  31&nbsp;  tail -n $CHECK_LINES $LOGFILE&#62; $TEMPFILE  32&nbsp;  #  Saves last 100 lines of system log file as temp file.  33&nbsp;  #  Necessary, since newer kernels generate many log messages at log on.  34&nbsp;  search=`grep $KEYWORD $TEMPFILE`  35&nbsp;  #  Checks for presence of the "IP address" phrase,  36&nbsp;  #+ indicating a successful logon.  37&nbsp;  38&nbsp;  if [ ! -z "$search" ] #  Quotes necessary because of possible spaces.  39&nbsp;  then  40&nbsp;     echo "On-line"  41&nbsp;     rm -f $TEMPFILE    #  Clean up temp file.  42&nbsp;     exit $ONLINE  43&nbsp;  else  44&nbsp;     echo -n "."        #  The -n option to echo suppresses newline,  45&nbsp;                        #+ so you get continuous rows of dots.  46&nbsp;  fi  47&nbsp;  48&nbsp;  sleep 1    49&nbsp;done    50&nbsp;  51&nbsp;  52&nbsp;#  Note: if you change the KEYWORD variable to "Exit",  53&nbsp;#+ this script can be used while on-line  54&nbsp;#+ to check for an unexpected logoff.  55&nbsp;  56&nbsp;# Exercise: Change the script, per the above note,  57&nbsp;#           and prettify it.  58&nbsp;  59&nbsp;exit 0  60&nbsp;  61&nbsp;  62&nbsp;# Nick Drage suggests an alternate method:  63&nbsp;  64&nbsp;while true  65&nbsp;  do ifconfig ppp0 | grep UP 1&#62; /dev/null &#38;&#38; echo "connected" &#38;&#38; exit 0  66&nbsp;  echo -n "."   # Prints dots (.....) until connected.  67&nbsp;  sleep 2  68&nbsp;done  69&nbsp;  70&nbsp;# Problem: Hitting Control-C to terminate this process may be insufficient.  71&nbsp;#+         (Dots may keep on echoing.)  72&nbsp;# Exercise: Fix this.  73&nbsp;  74&nbsp;  75&nbsp;  76&nbsp;# Stephane Chazelas has yet another alternative:  77&nbsp;  78&nbsp;CHECK_INTERVAL=1  79&nbsp;  80&nbsp;while ! tail -n 1 "$LOGFILE" | grep -q "$KEYWORD"  81&nbsp;do echo -n .  82&nbsp;   sleep $CHECK_INTERVAL  83&nbsp;done  84&nbsp;echo "On-line"  85&nbsp;  86&nbsp;# Exercise: Discuss the relative strengths and weaknesses  87&nbsp;#           of each of these various approaches.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>The <TTCLASS="OPTION">DEBUG</TT> argument to	<BCLASS="COMMAND">trap</B> causes a specified action to execute	after every command in a script. This permits tracing variables,	for example.      <DIVCLASS="EXAMPLE"><HR><ANAME="VARTRACE"></A><P><B>Example 29-7. Tracing a variable</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;   3&nbsp;trap 'echo "VARIABLE-TRACE&#62; \$variable = \"$variable\""' DEBUG   4&nbsp;# Echoes the value of $variable after every command.   5&nbsp;   6&nbsp;variable=29   7&nbsp;   8&nbsp;echo "Just initialized \"\$variable\" to $variable."   9&nbsp;  10&nbsp;let "variable *= 3"  11&nbsp;echo "Just multiplied \"\$variable\" by 3."  12&nbsp;  13&nbsp;exit $?  14&nbsp;  15&nbsp;#  The "trap 'command1 . . . command2 . . .' DEBUG" construct is  16&nbsp;#+ more appropriate in the context of a complex script,  17&nbsp;#+ where placing multiple "echo $variable" statements might be  18&nbsp;#+ clumsy and time-consuming.  19&nbsp;  20&nbsp;# Thanks, Stephane Chazelas for the pointer.  21&nbsp;  22&nbsp;  23&nbsp;Output of script:  24&nbsp;  25&nbsp;VARIABLE-TRACE&#62; $variable = ""  26&nbsp;VARIABLE-TRACE&#62; $variable = "29"  27&nbsp;Just initialized "$variable" to 29.  28&nbsp;VARIABLE-TRACE&#62; $variable = "29"  29&nbsp;VARIABLE-TRACE&#62; $variable = "87"  30&nbsp;Just multiplied "$variable" by 3.  31&nbsp;VARIABLE-TRACE&#62; $variable = "87"</PRE></TD></TR></TABLE><HR></DIV>      </P></TD></TR></TABLE></DIV><P>Of course, the <BCLASS="COMMAND">trap</B> command has other uses        aside from debugging.</P><DIVCLASS="EXAMPLE"><HR><ANAME="MULTIPLEPROC"></A><P><B>Example 29-8. Running multiple processes (on an SMP box)</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# parent.sh   3&nbsp;# Running multiple processes on an SMP box.   4&nbsp;# Author: Tedman Eng   5&nbsp;   6&nbsp;#  This is the first of two scripts,   7&nbsp;#+ both of which must be present in the current working directory.   8&nbsp;   9&nbsp;  10&nbsp;  11&nbsp;  12&nbsp;LIMIT=$1         # Total number of process to start  13&nbsp;NUMPROC=4        # Number of concurrent threads (forks?)  14&nbsp;PROCID=1         # Starting Process ID  15&nbsp;echo "My PID is $$"  16&nbsp;  17&nbsp;function start_thread() {  18&nbsp;        if [ $PROCID -le $LIMIT ] ; then  19&nbsp;                ./child.sh $PROCID&#38;  20&nbsp;                let "PROCID++"  21&nbsp;        else  22&nbsp;           echo "Limit reached."  23&nbsp;           wait  24&nbsp;           exit  25&nbsp;        fi  26&nbsp;}  27&nbsp;  28&nbsp;while [ "$NUMPROC" -gt 0 ]; do  29&nbsp;        start_thread;  30&nbsp;        let "NUMPROC--"  31&nbsp;done  32&nbsp;  33&nbsp;  34&nbsp;while true  35&nbsp;do  36&nbsp;  37&nbsp;trap "start_thread" SIGRTMIN  38&nbsp;  39&nbsp;done  40&nbsp;  41&nbsp;exit 0  42&nbsp;  43&nbsp;  44&nbsp;  45&nbsp;# ======== Second script follows ========  46&nbsp;  47&nbsp;  48&nbsp;#!/bin/bash  49&nbsp;# child.sh  50&nbsp;# Running multiple processes on an SMP box.  51&nbsp;# This script is called by parent.sh.  52&nbsp;# Author: Tedman Eng  53&nbsp;  54&nbsp;temp=$RANDOM  55&nbsp;index=$1  56&nbsp;shift  57&nbsp;let "temp %= 5"  58&nbsp;let "temp += 4"  59&nbsp;echo "Starting $index  Time:$temp" "$@"  60&nbsp;sleep ${temp}  61&nbsp;echo "Ending $index"  62&nbsp;kill -s SIGRTMIN $PPID  63&nbsp;  64&nbsp;exit 0  65&nbsp;  66&nbsp;  67&nbsp;# ======================= SCRIPT AUTHOR'S NOTES ======================= #  68&nbsp;#  It's not completely bug free.  69&nbsp;#  I ran it with limit = 500 and after the first few hundred iterations,  70&nbsp;#+ one of the concurrent threads disappeared!  71&nbsp;#  Not sure if this is collisions from trap signals or something else.  72&nbsp;#  Once the trap is received, there's a brief moment while executing the  73&nbsp;#+ trap handler but before the next trap is set.  During this time, it may  74&nbsp;#+ be possible to miss a trap signal, thus miss spawning a child process.  75&nbsp;  76&nbsp;#  No doubt someone may spot the bug and will be writing   77&nbsp;#+ . . . in the future.  78&nbsp;  79&nbsp;  80&nbsp;  81&nbsp;# ===================================================================== #  82&nbsp;  83&nbsp;  84&nbsp;  85&nbsp;# ----------------------------------------------------------------------#  86&nbsp;  87&nbsp;  88&nbsp;  89&nbsp;#################################################################  90&nbsp;# The following is the original script written by Vernia Damiano.  91&nbsp;# Unfortunately, it doesn't work properly.  92&nbsp;#################################################################  93&nbsp;  94&nbsp;#!/bin/bash  95&nbsp;  96&nbsp;#  Must call script with at least one integer parameter  97&nbsp;#+ (number of concurrent processes).  98&nbsp;#  All other parameters are passed through to the processes started.  99&nbsp; 100&nbsp; 101&nbsp;INDICE=8        # Total number of process to start 102&nbsp;TEMPO=5         # Maximum sleep time per process 103&nbsp;E_BADARGS=65    # No arg(s) passed to script. 104&nbsp; 105&nbsp;if [ $# -eq 0 ] # Check for at least one argument passed to script. 106&nbsp;then 107&nbsp;  echo "Usage: `basename $0` number_of_processes [passed params]" 108&nbsp;  exit $E_BADARGS 109&nbsp;fi 110&nbsp; 111&nbsp;NUMPROC=$1              # Number of concurrent process 112&nbsp;shift 113&nbsp;PARAMETRI=( "$@" )      # Parameters of each process 114&nbsp; 115&nbsp;function avvia() { 116&nbsp;         local temp 117&nbsp;         local index 118&nbsp;         temp=$RANDOM 119&nbsp;         index=$1 120&nbsp;         shift 121&nbsp;         let "temp %= $TEMPO" 122&nbsp;         let "temp += 1" 123&nbsp;         echo "Starting $index Time:$temp" "$@" 124&nbsp;         sleep ${temp} 125&nbsp;         echo "Ending $index" 126&nbsp;         kill -s SIGRTMIN $$ 127&nbsp;} 128&nbsp; 129&nbsp;function parti() { 130&nbsp;         if [ $INDICE -gt 0 ] ; then 131&nbsp;              avvia $INDICE "${PARAMETRI[@]}" &#38; 132&nbsp;                let "INDICE--" 133&nbsp;         else 134&nbsp;                trap : SIGRTMIN 135&nbsp;         fi 136&nbsp;} 137&nbsp; 138&nbsp;trap parti SIGRTMIN 139&nbsp; 140&nbsp;while [ "$NUMPROC" -gt 0 ]; do 141&nbsp;         parti; 142&nbsp;         let "NUMPROC--" 143&nbsp;done 144&nbsp; 145&nbsp;wait 146&nbsp;trap - SIGRTMIN 147&nbsp; 148&nbsp;exit $? 149&nbsp; 150&nbsp;: &#60;&#60;SCRIPT_AUTHOR_COMMENTS 151&nbsp;I had the need to run a program, with specified options, on a number of 152&nbsp;different files, using a SMP machine. So I thought [I'd] keep running 153&nbsp;a specified number of processes and start a new one each time . . . one 154&nbsp;of these terminates. 155&nbsp; 156&nbsp;The "wait" instruction does not help, since it waits for a given process 157&nbsp;or *all* process started in background. So I wrote [this] bash script 158&nbsp;that can do the job, using the "trap" instruction. 159&nbsp;  --Vernia Damiano 160&nbsp;SCRIPT_AUTHOR_COMMENTS</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P><TTCLASS="USERINPUT"><B>trap '' SIGNAL</B></TT> (two adjacent	apostrophes) disables SIGNAL for the remainder of the	script. <TTCLASS="USERINPUT"><B>trap SIGNAL</B></TT> restores	the functioning of SIGNAL once more. This is useful to	protect a critical portion of a script from an undesirable	interrupt.</P></TD></TR></TABLE></DIV><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;	trap '' 2  # Signal 2 is Control-C, now disabled.   2&nbsp;	command   3&nbsp;	command   4&nbsp;	command   5&nbsp;	trap 2     # Reenables Control-C   6&nbsp;	</PRE></TD></TR></TABLE></P><TABLECLASS="SIDEBAR"BORDER="1"CELLPADDING="5"><TR><TD><DIVCLASS="SIDEBAR"><ANAME="AEN17884"></A><P><AHREF="bashver3.html#BASH3REF">Version 3</A> of Bash adds the	following special variables for use by the debugger.       <OLTYPE="1"><LI><P>$BASH_ARGC</P></LI><LI><P>$BASH_ARGV</P></LI><LI><P>$BASH_COMMAND</P></LI><LI><P>$BASH_EXECUTION_STRING</P></LI><LI><P>$BASH_LINENO</P></LI><LI><P>$BASH_SOURCE</P></LI><LI><P><AHREF="variables2.html#BASHSUBSHELLREF">$BASH_SUBSHELL</A></P></LI></OL></P></DIV></TD></TR></TABLE></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN17836"HREF="debugging.html#AEN17836">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>By convention, <TTCLASS="REPLACEABLE"><I>signal		0</I></TT> is assigned to <AHREF="exit-status.html#EXITCOMMANDREF">exit</A>.  </P></TD></TR></TABLE><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="zeros.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="options.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Of Zeros and Nulls</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part5.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Options</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -