📄 ch45_08.htm
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 45] 45.8 Handling Signals to Child Processes </TITLE><METANAME="DC.title"CONTENT="UNIX Power Tools"><METANAME="DC.creator"CONTENT="Jerry Peek, Tim O'Reilly & Mike Loukides"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1998-08-04T21:54:27Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-260-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch45_01.htm"TITLE="45. Shell Programming for the Initiated"><LINKREL="prev"HREF="ch45_07.htm"TITLE="45.7 The exec Command "><LINKREL="next"HREF="ch45_09.htm"TITLE='45.9 The Unappreciated Bourne Shell ":" Operator'></HEAD><BODYBGCOLOR="#FFFFFF"TEXT="#000000"><DIVCLASS="htmlnav"><H1><IMGSRC="gifs/smbanner.gif"ALT="UNIX Power Tools"USEMAP="#srchmap"BORDER="0"></H1><MAPNAME="srchmap"><AREASHAPE="RECT"COORDS="0,0,466,58"HREF="index.htm"ALT="UNIX Power Tools"><AREASHAPE="RECT"COORDS="467,0,514,18"HREF="jobjects/fsearch.htm"ALT="Search this book"></MAP><TABLEWIDTH="515"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_07.htm"TITLE="45.7 The exec Command "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.7 The exec Command "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1">Chapter 45<BR>Shell Programming for the Initiated</FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_09.htm"TITLE='45.9 The Unappreciated Bourne Shell ":" Operator'><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT='Next: 45.9 The Unappreciated Bourne Shell ":" Operator'BORDER="0"></A></TD></TR></TABLE> <HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-0198">45.8 Handling Signals to Child Processes </A></H2><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-52609"></A><ACLASS="indexterm"NAME="AUTOID-52612"></A><ACLASS="indexterm"NAME="AUTOID-52615"></A><ACLASS="indexterm"NAME="UPT-ART-198-IX-SIGNAL-HANDLING-IN-BOURNE-SHELLS"></A><ACLASS="indexterm"NAME="UPT-ART-198-IX-SIGNAL-HANDLING-OF-SUBPROCESSES"></A><ACLASS="indexterm"NAME="UPT-ART-198-IX-SUBPROCESSES"></A>The Bourne shell<SPANCLASS="link"><EMCLASS="emphasis">trap</EM> command (<ACLASS="linkend"HREF="ch44_12.htm"TITLE="Trapping Exits Caused by Interrupts ">44.12</A>)</SPAN>controls what the shell does when it gets an interrupt or signal (from the<SPANCLASS="link"><EMCLASS="emphasis">kill</EM> (<ACLASS="linkend"HREF="ch38_10.htm"TITLE="Destroying Processes with kill ">38.10</A>)</SPAN>command, from a keyboard character like CTRL-c, and so on).To run an<SPANCLASS="link">external command (<ACLASS="linkend"HREF="ch01_10.htm"TITLE="Internal and External Commands ">1.10</A>)</SPAN>-like an editor or a simple command such as <EMCLASS="emphasis">sort</EM>-the shell starts a<SPANCLASS="link">child process (<ACLASS="linkend"HREF="ch38_03.htm"TITLE="Managing Processes: Overall Concepts ">38.3</A>)</SPAN>(subprocess). If the program running in the child process wantsto handle its own signals, the parent shell should probably passsignals on to the child process. For example, you might run<EMCLASS="emphasis">vi</EM> as a child process and want to send a CTRL-c to stop<EMCLASS="emphasis">vi</EM> from what it's doing, but not want the CTRL-c to killthe parent shell script.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-52636"></A><ACLASS="indexterm"NAME="AUTOID-52639"></A><ACLASS="indexterm"NAME="AUTOID-52642"></A>When the parent process gets a signal, should it die or keep running?Should the child get the signal or not? The Bourne shell gives you afair amount of flexibility in signal handling. The bad news is thatmost <EMCLASS="emphasis">sh</EM> manual pages don't say much about this. And no manualpage I've seen explains a useful choice: using the<SPANCLASS="link"><CODECLASS="literal">:</CODE> (colon) operator (<ACLASS="linkend"HREF="ch45_09.htm"TITLE='The Unappreciated Bourne Shell ":" Operator'>45.9</A>)</SPAN>with <EMCLASS="emphasis">trap</EM>.<ACLASS="xref"HREF="ch45_08.htm#UPT-ART-198-TAB-0"TITLE="trap Arguments (for Most Bourne Shells)">Table 45.1</A>shows your choices.<ACLASS="indexterm"NAME="AUTOID-52649"></A></P><TABLECLASS="table"><CAPTIONCLASS="table"><ACLASS="title"NAME="UPT-ART-198-TAB-0">Table 45.1: trap Arguments (for Most Bourne Shells)</A></CAPTION><THEADCLASS="thead"><TRCLASS="row"VALIGN="TOP"><THCLASS="entry"ALIGN="LEFT"ROWSPAN="1"COLSPAN="1">Argument</TH><THCLASS="entry"ALIGN="LEFT"ROWSPAN="1"COLSPAN="1">Effect</TH></TR></THEAD><TBODYCLASS="tbody"><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1">""</TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1">Ignore signal, don't pass signal to child.</TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1">:</TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1">(undocumented) Ignore signal, pass signal to child.</TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1">"<CODECLASS="replaceable"><I>command-line</I></CODE>"</TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para">Run <EMCLASS="emphasis">command-line</EM> with variable and command substitution done when <EMCLASS="emphasis">trap</EM> set; don't pass signal to child.</P></TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1">'<CODECLASS="replaceable"><I>command-line</I></CODE>'</TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para">Run <EMCLASS="emphasis">command-line</EM> with variable and command substitution donewhen <EMCLASS="emphasis">trap</EM> executed; don't pass signal to child.</P></TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1">No argument</TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para">Reset signal handling to default (usually, parent terminates).Pass signal to child.</P></TD></TR></TBODY></TABLE><PCLASS="para">Because so much of this is undocumented, I won't try to give you "theanswers" for how it should work with your shell.Instead, here are two shell scripts that let you experiment with yourshell's signal handling.One script, named <EMCLASS="emphasis">parent</EM>, starts the second script, <EMCLASS="emphasis">child</EM>.The <EMCLASS="emphasis">child</EM> script sets some traps, then starts<SPANCLASS="link"><EMCLASS="emphasis">sleep</EM> (<ACLASS="linkend"HREF="ch40_02.htm"TITLE="Waiting a Little While: sleep ">40.2</A>)</SPAN>so it'll be there when you send a signal.This lets you use CTRL-c or other interrupts,if <EMCLASS="emphasis">parent</EM> is running inthe foreground - or the <EMCLASS="emphasis">kill</EM> command with signal numbers, if you'veput <EMCLASS="emphasis">parent</EM> in the background.You can edit the <EMCLASS="emphasis">trap</EM> lines in the two scripts to test the setupyou want to use.</P><PCLASS="para">Here's an example.I'll start <EMCLASS="emphasis">parent</EM> in the background from the C shell, then send it asignal 1 ("hangup" signal):</P><PCLASS="para"><TABLECLASS="screen.co"BORDER="1"><TR><THVALIGN="TOP"><PRECLASS="calloutlist"> <ACLASS="co"HREF="ch12_01.htm"TITLE="12.1 Job Control: Work Faster, Stop Runaway Jobs ">%1</A> </PRE></TH><TDVALIGN="TOP"><PRECLASS="screen">% <CODECLASS="userinput"><B>parent &</B></CODE>[1] 8669parent startedchild started. pid is 8671% <CODECLASS="userinput"><B>kill -1 %1</B></CODE>./child: % 8671 Hangupchild got a signal 1child exitingparent still running after child exited <ICLASS="lineannotation">...1000 seconds later...</I>parent exiting[1] + Done parent</PRE></TD></TR></TABLE></P><PCLASS="para">Now, the scripts:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>cat parent</B></CODE>#!/bin/shecho parent startedtrap "echo parent exiting; exit" 0trap : 1 # pass signal 1 to child but don't dietrap "" 2 # ignore signal 2, block from childtrap "echo parent got signal 15" 15 # ignore signal 15, send to child # die on other signals, send to child<ACLASS="indexterm"NAME="AUTOID-52706"></A>childecho parent still running after child exitedsleep 1000% <CODECLASS="userinput"><B>cat child</B></CODE>#! /bin/shecho child started. pid is $$.trap 'echo child exiting; exit' 0trap 'echo child got a signal 1' 1trap '' 2 # ignore signal 2trap 'echo child got a signal 3' 3sleep 1000 # wait a long time for a signal</PRE></BLOCKQUOTE></P><PCLASS="para">Even with this help, the way signal handling works might not be too clear.For more on signal handling, see a book that coversUNIX internals on your system.</P><ACLASS="indexterm"NAME="AUTOID-52711"></A><ACLASS="indexterm"NAME="AUTOID-52712"></A><ACLASS="indexterm"NAME="AUTOID-52713"></A><DIVCLASS="sect1info"><PCLASS="SECT1INFO">- <SPANCLASS="authorinitials">JP</SPAN></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="515"TITLE="footer"><TABLEWIDTH="515"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_07.htm"TITLE="45.7 The exec Command "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.7 The exec Command "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><ACLASS="book"HREF="index.htm"TITLE="UNIX Power Tools"><IMGSRC="gifs/txthome.gif"SRC="gifs/txthome.gif"ALT="UNIX Power Tools"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_09.htm"TITLE='45.9 The Unappreciated Bourne Shell ":" Operator'><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT='Next: 45.9 The Unappreciated Bourne Shell ":" Operator'BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">45.7 The exec Command </TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><ACLASS="index"HREF="index/idx_0.htm"TITLE="Book Index"><IMGSRC="gifs/index.gif"SRC="gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172">45.9 The Unappreciated Bourne Shell ":" Operator</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="515"TITLE="footer"><IMGSRC="gifs/smnavbar.gif"SRC="gifs/smnavbar.gif"USEMAP="#map"BORDER="0"ALT="The UNIX CD Bookshelf Navigation"><MAPNAME="map"><AREASHAPE="RECT"COORDS="0,0,73,21"HREF="../index.htm"ALT="The UNIX CD Bookshelf"><AREASHAPE="RECT"COORDS="74,0,163,21"HREF="index.htm"ALT="UNIX Power Tools"><AREASHAPE="RECT"COORDS="164,0,257,21"HREF="../unixnut/index.htm"ALT="UNIX in a Nutshell"><AREASHAPE="RECT"COORDS="258,0,321,21"HREF="../vi/index.htm"ALT="Learning the vi Editor"><AREASHAPE="RECT"COORDS="322,0,378,21"HREF="../sedawk/index.htm"ALT="sed & awk"><AREASHAPE="RECT"COORDS="379,0,438,21"HREF="../ksh/index.htm"ALT="Learning the Korn Shell"><AREASHAPE="RECT"COORDS="439,0,514,21"HREF="../lrnunix/index.htm"ALT="Learning the UNIX Operating System"></MAP></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -