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

📄 ch45_21.htm

📁 the unix power tools
💻 HTM
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 45] 45.21 n&gt;&amp;m: Swap Standard Output and Standard Error </TITLE><METANAME="DC.title"CONTENT="UNIX Power Tools"><METANAME="DC.creator"CONTENT="Jerry Peek, Tim O'Reilly &amp; Mike Loukides"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1998-08-04T21:54:48Z"><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_20.htm"TITLE="45.20 Overview: Open Files and File Descriptors "><LINKREL="next"HREF="ch45_22.htm"TITLE="45.22 Handling Files Line-by-Line "></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_20.htm"TITLE="45.20 Overview: Open Files and File Descriptors "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.20 Overview: Open Files and File Descriptors "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_22.htm"TITLE="45.22 Handling Files Line-by-Line "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 45.22 Handling Files Line-by-Line "BORDER="0"></A></TD></TR></TABLE>&nbsp;<HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-7930">45.21 n&gt;&amp;m: Swap Standard Output and Standard Error </A></H2><PCLASS="para"><ACLASS="indexterm"NAME="UPT-ART-7930-IX-NGT-AMP-M-DESCRIBED"></A><ACLASS="indexterm"NAME="UPT-ART-7930-IX-FILE-DESCRIPTORS-REDIRECTING"></A><ACLASS="indexterm"NAME="UPT-ART-7930-IX-REDIRECTING-FILE-DESCRIPTORS"></A><ACLASS="indexterm"NAME="UPT-ART-7930-IX-REDIRECTING-STANDARD-ERROR"></A><ACLASS="indexterm"NAME="UPT-ART-7930-IX-REDIRECTING-STANDARD-OUTPUT"></A><ACLASS="indexterm"NAME="UPT-ART-7930-IX-STANDARD-ERRORS-REDIRECTING"></A><ACLASS="indexterm"NAME="UPT-ART-7930-IX-STANDARD-OUTPUT-REDIRECTING"></A>By default, a command's standard error goes to your terminal.The standard output goes to the terminal or is redirected somewhere(to a file, down a pipe, into backquotes).</P><PCLASS="para">Sometimes you want the opposite.For instance, you may need to send a command's standard output to the screenand grab the error messages (standard error) withbackquotes.Or, you might want to send a command's standard output to a file and thestandard error down a pipe to an error-processing command.Here's how to do that in the Bourne shell.(The C shell can't do this.)</P><PCLASS="para">File descriptors 0, 1, and 2 are, respectively, the standardinput, standard output, and standard error(article<ACLASS="xref"HREF="ch45_20.htm"TITLE="Overview: Open Files and File Descriptors ">45.20</A>explains).Without redirection, they're all associated with the terminal file<SPANCLASS="link"><EMCLASS="emphasis">/dev/tty</EM> (<ACLASS="linkend"HREF="ch45_20.htm"TITLE="Overview: Open Files and File Descriptors ">45.20</A>)</SPAN>.It's easy to redirect any descriptor to any file&nbsp;- if you know the filename.For instance, to redirect file descriptor 2 to <EMCLASS="emphasis">errfile</EM>, type:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">$ <CODECLASS="replaceable"><I>command</I></CODE><CODECLASS="userinput"><B> 2&gt;errfile</B></CODE></PRE></BLOCKQUOTE></P><PCLASS="para">You know that a pipe and backquotes also redirect the standard output:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">$ <CODECLASS="replaceable"><I>command</I></CODE><CODECLASS="userinput"><B> | ...</B></CODE>$ <CODECLASS="userinput"><B>var=`</B></CODE><CODECLASS="replaceable"><I>command</I></CODE><CODECLASS="userinput"><B>`</B></CODE></PRE></BLOCKQUOTE></P><PCLASS="para">But there's no filename associated with the pipe or backquotes, soyou can't use the <CODECLASS="literal">2&gt;</CODE> redirection.You need to rearrange the file descriptors without knowing the file(or whatever) that they're associated with.Here's how.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-53713"></A><ACLASS="indexterm"NAME="AUTOID-53716"></A><ACLASS="indexterm"NAME="AUTOID-53719"></A>Let's start slowly: by sending both standard output and standard errorto the pipe or backquotes.The Bourne shell operator <CODECLASS="replaceable"><I>n</I></CODE><CODECLASS="literal">&gt;&amp;</CODE><CODECLASS="replaceable"><I>m</I></CODE> rearranges the files and file descriptors.It says &quot;make file descriptor <EMCLASS="emphasis">n</EM> point to the same file asfile descriptor <EMCLASS="emphasis">m</EM>.&quot;Let'suse that operator on the previous example.We'll send standard error to the same place standard output is going:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">$ <CODECLASS="replaceable"><I>command</I></CODE> <CODECLASS="userinput"><B>2&gt;&amp;1 | ...</B></CODE>$ <CODECLASS="userinput"><B>var=`</B></CODE><CODECLASS="replaceable"><I>command</I></CODE><CODECLASS="userinput"><B> 2&gt;&amp;1`</B></CODE></PRE></BLOCKQUOTE></P><PCLASS="para">In both those examples, <CODECLASS="literal">2&gt;&amp;1</CODE> means &quot;send standard error (filedescriptor 2) to the same place standard output (file descriptor 1)is going.&quot;Simple, eh?</P><PCLASS="para">You can use more than one of those <CODECLASS="replaceable"><I>n</I></CODE><CODECLASS="literal">&gt;&amp;</CODE><CODECLASS="replaceable"><I>m</I></CODE> operators.The shell reads them left-to-right before it executes the command.</P><PCLASS="para">&quot;Oh!&quot; you might say,&quot;To swap standard output and standard error&nbsp;- make <EMCLASS="emphasis">stderr</EM> go down apipe and <EMCLASS="emphasis">stdout</EM> go to the screen-I could do this!&quot;</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">$ <CODECLASS="replaceable"><I>command</I></CODE> <CODECLASS="userinput"><B>2&gt;&amp;1 1&gt;&amp;2 | ...</B></CODE>     <EMCLASS="emphasis">(wrong...)</EM></PRE></BLOCKQUOTE></P><PCLASS="para">Sorry, Charlie.When the shell sees <CODECLASS="literal">2&gt;&amp;1&nbsp;1&gt;&amp;2</CODE>, the shell first does <CODECLASS="literal">2&gt;&amp;1</CODE>.You've seen that before&nbsp;- it makes file descriptor 2 (<EMCLASS="emphasis">stderr</EM>) go the same place as file descriptor 1 (<EMCLASS="emphasis">stdout</EM>).Then, the shell does <CODECLASS="literal">1&gt;&amp;2</CODE>.It makes <EMCLASS="emphasis">stdout</EM> (<CODECLASS="literal">1</CODE>) go the same place as <EMCLASS="emphasis">stderr</EM>(<CODECLASS="literal">2</CODE>)... but <EMCLASS="emphasis">stderr</EM> is already going the same place as<EMCLASS="emphasis">stdout</EM>, down the pipe.</P><PCLASS="para">This is one place the other file descriptors, 3 through 9, come in handy.They normally aren't used.You can use one of them as a &quot;holding place,&quot; to remember where anotherfile descriptor &quot;pointed.&quot;For example, one way to read the operator <CODECLASS="literal">3&gt;&amp;2</CODE> is &quot;make<CODECLASS="literal">3</CODE> point the same place as <CODECLASS="literal">2</CODE>.&quot;After you use <CODECLASS="literal">3&gt;&amp;2</CODE> to grab the location of <CODECLASS="literal">2</CODE>,you can make <CODECLASS="literal">2</CODE> point somewhere else.Then, make <CODECLASS="literal">1</CODE> point where <CODECLASS="literal">2</CODE> used to (where <CODECLASS="literal">3</CODE>points now).</P><PCLASS="para">We'll take that step-by-step below.The command line you want is one of these:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">$ <CODECLASS="replaceable"><I>command</I></CODE> <CODECLASS="userinput"><B>3&gt;&amp;2 2&gt;&amp;1 1&gt;&amp;3 | ...</B></CODE>$ <CODECLASS="userinput"><B>var=`</B></CODE><CODECLASS="replaceable"><I>command</I></CODE><CODECLASS="userinput"><B> 3&gt;&amp;2 2&gt;&amp;1 1&gt;&amp;3`</B></CODE></PRE></BLOCKQUOTE></P><PCLASS="para">How does it work?The next four figuresbreak the second command line (with the backquotes) into the samesteps the shell follows as it rearranges the file descriptors.You can try these on your terminal, if you'd like.Each figure adds another <CODECLASS="replaceable"><I>n</I></CODE><CODECLASS="literal">&gt;&amp;</CODE><CODECLASS="replaceable"><I>m</I></CODE> operator andshows the location of each file descriptor after that operator.</P><PCLASS="para">The figures use a <EMCLASS="emphasis">grep</EM> command reading two files.<EMCLASS="emphasis">afone</EM> is readable and <EMCLASS="emphasis">grep</EM> finds one matching line in it;the line is written to the standard output.<EMCLASS="emphasis">bfoen</EM> is misspelled and so is not readable; <EMCLASS="emphasis">grep</EM> writes anerror message to the standard error.In each figure, you'll see the terminal output (if any) just after thevariable-setting command with the backquotes.The text grabbed by the backquotes goes into the shell variable;the <EMCLASS="emphasis">echo</EM> command shows that text.</P><PCLASS="para">By <ACLASS="xref"HREF="ch45_21.htm#UPT-ART-7930-FIG-3"TITLE="File Descriptors After 3&gt;&amp;2&nbsp;2&gt;&amp;1&nbsp;1&gt;&amp;3 Redirection">Figure 45.6</A>the redirection is correct.Standard output goes to the screen, and standard error is captured bythe backquotes.</P><PCLASS="para"><H4CLASS="figure"><ACLASS="title"NAME="UPT-ART-7930-FIG-0">Figure 45.3: File Descriptors Before Redirection</A></H4><IMGCLASS="graphic"SRC="figs/7930a.gif"ALT="Figure 45.3"></P><PCLASS="para"><H4CLASS="figure"><ACLASS="title"NAME="UPT-ART-7930-FIG-1">Figure 45.4: File Descriptors After 3&gt;&amp;2 Redirection</A></H4><IMGCLASS="graphic"SRC="figs/7930b.gif"ALT="Figure 45.4"></P><PCLASS="para"><H4CLASS="figure"><ACLASS="title"NAME="UPT-ART-7930-FIG-2">Figure 45.5: File Descriptors After 3&gt;&amp;2&nbsp;2&gt;&amp;1 Redirection</A></H4><IMGCLASS="graphic"SRC="figs/7930c.gif"ALT="Figure 45.5"></P><PCLASS="para"><H4CLASS="figure"><ACLASS="title"NAME="UPT-ART-7930-FIG-3">Figure 45.6: File Descriptors After 3&gt;&amp;2&nbsp;2&gt;&amp;1&nbsp;1&gt;&amp;3 Redirection</A></H4><IMGCLASS="graphic"SRC="figs/7930d.gif"ALT="Figure 45.6"><ACLASS="indexterm"NAME="AUTOID-53807"></A><ACLASS="indexterm"NAME="AUTOID-53810"></A></P><PCLASS="para">Open files are automatically closed when a process exits.But it's safer to close the files yourself as soon as you're done with them.That way, if you forget and use the same descriptor later for somethingelse (for instance, use F.D. 3 to redirect some other command, or asubprocess uses F.D. 3), you won't run into conflicts.Use <CODECLASS="replaceable"><I>m</I></CODE><CODECLASS="literal">&lt;&amp;-</CODE> to close input file descriptor <CODECLASS="replaceable"><I>m</I></CODE> and<CODECLASS="replaceable"><I>m</I></CODE><CODECLASS="literal">&gt;&amp;-</CODE> to close output file descriptor <CODECLASS="replaceable"><I>m</I></CODE>.If you need to close standard input, use <CODECLASS="literal">&lt;&amp;-</CODE>;<CODECLASS="literal">&gt;&amp;-</CODE> will close standard output.<ACLASS="indexterm"NAME="AUTOID-53822"></A><ACLASS="indexterm"NAME="AUTOID-53823"></A><ACLASS="indexterm"NAME="AUTOID-53824"></A><ACLASS="indexterm"NAME="AUTOID-53825"></A><ACLASS="indexterm"NAME="AUTOID-53826"></A><ACLASS="indexterm"NAME="AUTOID-53827"></A><ACLASS="indexterm"NAME="AUTOID-53828"></A></P><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_20.htm"TITLE="45.20 Overview: Open Files and File Descriptors "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.20 Overview: Open Files and File Descriptors "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_22.htm"TITLE="45.22 Handling Files Line-by-Line "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 45.22 Handling Files Line-by-Line "BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">45.20 Overview: Open Files and File Descriptors </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.22 Handling Files Line-by-Line </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 &amp; 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 + -