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

📄 io-redirection.html

📁 Shall高级编程
💻 HTML
📖 第 1 页 / 共 2 页
字号:
>        </P><P>For a more detailed introduction to I/O redirection see	  <AHREF="ioredirintro.html">Appendix E</A>.</P><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="AEN16560"></A>19.1. Using <ICLASS="FIRSTTERM">exec</I></H1><P><ANAME="USINGEXECREF"></A></P><P>An <BCLASS="COMMAND">exec &#60;filename</B> command redirects	  <TTCLASS="FILENAME">stdin</TT> to a file. From that point on, all	  <TTCLASS="FILENAME">stdin</TT> comes from that file, rather than	  its normal source (usually keyboard input). This provides a	  method of reading a file line by line and possibly parsing	  each line of input using <AHREF="sedawk.html#SEDREF">sed</A>	  and/or <AHREF="awk.html#AWKREF">awk</A>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="REDIR1"></A><P><B>Example 19-1. Redirecting <TTCLASS="FILENAME">stdin</TT> using	  <ICLASS="FIRSTTERM">exec</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# Redirecting stdin using 'exec'.   3&nbsp;   4&nbsp;   5&nbsp;exec 6&#60;&#38;0          # Link file descriptor #6 with stdin.   6&nbsp;                   # Saves stdin.   7&nbsp;   8&nbsp;exec &#60; data-file   # stdin replaced by file "data-file"   9&nbsp;  10&nbsp;read a1            # Reads first line of file "data-file".  11&nbsp;read a2            # Reads second line of file "data-file."  12&nbsp;  13&nbsp;echo  14&nbsp;echo "Following lines read from file."  15&nbsp;echo "-------------------------------"  16&nbsp;echo $a1  17&nbsp;echo $a2  18&nbsp;  19&nbsp;echo; echo; echo  20&nbsp;  21&nbsp;exec 0&#60;&#38;6 6&#60;&#38;-  22&nbsp;#  Now restore stdin from fd #6, where it had been saved,  23&nbsp;#+ and close fd #6 ( 6&#60;&#38;- ) to free it for other processes to use.  24&nbsp;#  25&nbsp;# &#60;&#38;6 6&#60;&#38;-    also works.  26&nbsp;  27&nbsp;echo -n "Enter data  "  28&nbsp;read b1  # Now "read" functions as expected, reading from normal stdin.  29&nbsp;echo "Input read from stdin."  30&nbsp;echo "----------------------"  31&nbsp;echo "b1 = $b1"  32&nbsp;  33&nbsp;echo  34&nbsp;  35&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P>Similarly, an <BCLASS="COMMAND">exec &#62;filename</B>	  command redirects <TTCLASS="FILENAME">stdout</TT> to a designated	  file.  This sends all command output that would normally go	  to <TTCLASS="FILENAME">stdout</TT> to that file.</P><DIVCLASS="IMPORTANT"><TABLECLASS="IMPORTANT"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/important.png"HSPACE="5"ALT="Important"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>	  <BCLASS="COMMAND">exec N &#62; filename</B> affects the entire	  script or <ICLASS="FIRSTTERM">current shell</I>. Redirection in	  the <AHREF="special-chars.html#PROCESSIDREF">PID</A> of the script or shell	  from that point on has changed. However . . .        </P><P>	  <BCLASS="COMMAND">N &#62; filename</B> affects only the newly-forked process,	  not the entire script or shell.        </P><P>Thank you, Ahmed Darwish, for pointing this out.</P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="REASSIGNSTDOUT"></A><P><B>Example 19-2. Redirecting <TTCLASS="FILENAME">stdout</TT> using	  <ICLASS="FIRSTTERM">exec</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# reassign-stdout.sh   3&nbsp;   4&nbsp;LOGFILE=logfile.txt   5&nbsp;   6&nbsp;exec 6&#62;&#38;1           # Link file descriptor #6 with stdout.   7&nbsp;                    # Saves stdout.   8&nbsp;   9&nbsp;exec &#62; $LOGFILE     # stdout replaced with file "logfile.txt".  10&nbsp;  11&nbsp;# ----------------------------------------------------------- #  12&nbsp;# All output from commands in this block sent to file $LOGFILE.  13&nbsp;  14&nbsp;echo -n "Logfile: "  15&nbsp;date  16&nbsp;echo "-------------------------------------"  17&nbsp;echo  18&nbsp;  19&nbsp;echo "Output of \"ls -al\" command"  20&nbsp;echo  21&nbsp;ls -al  22&nbsp;echo; echo  23&nbsp;echo "Output of \"df\" command"  24&nbsp;echo  25&nbsp;df  26&nbsp;  27&nbsp;# ----------------------------------------------------------- #  28&nbsp;  29&nbsp;exec 1&#62;&#38;6 6&#62;&#38;-      # Restore stdout and close file descriptor #6.  30&nbsp;  31&nbsp;echo  32&nbsp;echo "== stdout now restored to default == "  33&nbsp;echo  34&nbsp;ls -al  35&nbsp;echo  36&nbsp;  37&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="UPPERCONV"></A><P><B>Example 19-3. Redirecting both <TTCLASS="FILENAME">stdin</TT> and	  <TTCLASS="FILENAME">stdout</TT> in the same script with	  <ICLASS="FIRSTTERM">exec</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# upperconv.sh   3&nbsp;# Converts a specified input file to uppercase.   4&nbsp;   5&nbsp;E_FILE_ACCESS=70   6&nbsp;E_WRONG_ARGS=71   7&nbsp;   8&nbsp;if [ ! -r "$1" ]     # Is specified input file readable?   9&nbsp;then  10&nbsp;  echo "Can't read from input file!"  11&nbsp;  echo "Usage: $0 input-file output-file"  12&nbsp;  exit $E_FILE_ACCESS  13&nbsp;fi                   #  Will exit with same error  14&nbsp;                     #+ even if input file ($1) not specified (why?).  15&nbsp;  16&nbsp;if [ -z "$2" ]  17&nbsp;then  18&nbsp;  echo "Need to specify output file."  19&nbsp;  echo "Usage: $0 input-file output-file"  20&nbsp;  exit $E_WRONG_ARGS  21&nbsp;fi  22&nbsp;  23&nbsp;  24&nbsp;exec 4&#60;&#38;0  25&nbsp;exec &#60; $1            # Will read from input file.  26&nbsp;  27&nbsp;exec 7&#62;&#38;1  28&nbsp;exec &#62; $2            # Will write to output file.  29&nbsp;                     # Assumes output file writable (add check?).  30&nbsp;  31&nbsp;# -----------------------------------------------  32&nbsp;    cat - | tr a-z A-Z   # Uppercase conversion.  33&nbsp;#   ^^^^^                # Reads from stdin.  34&nbsp;#           ^^^^^^^^^^   # Writes to stdout.  35&nbsp;# However, both stdin and stdout were redirected.  36&nbsp;# Note that the 'cat' can be omitted.  37&nbsp;# -----------------------------------------------  38&nbsp;  39&nbsp;exec 1&#62;&#38;7 7&#62;&#38;-       # Restore stout.  40&nbsp;exec 0&#60;&#38;4 4&#60;&#38;-       # Restore stdin.  41&nbsp;  42&nbsp;# After restoration, the following line prints to stdout as expected.  43&nbsp;echo "File \"$1\" written to \"$2\" as uppercase conversion."  44&nbsp;  45&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P>I/O redirection is a clever way of avoiding the dreaded <AHREF="subshells.html#PARVIS">inaccessible variables within a subshell</A>      problem.</P><DIVCLASS="EXAMPLE"><HR><ANAME="AVOIDSUBSHELL"></A><P><B>Example 19-4. Avoiding a subshell</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# avoid-subshell.sh   3&nbsp;# Suggested by Matthew Walker.   4&nbsp;   5&nbsp;Lines=0   6&nbsp;   7&nbsp;echo   8&nbsp;   9&nbsp;cat myfile.txt | while read line;  10&nbsp;                 do {  11&nbsp;                   echo $line  12&nbsp;                   (( Lines++ ));  #  Incremented values of this variable  13&nbsp;                                   #+ inaccessible outside loop.  14&nbsp;                                   #  Subshell problem.  15&nbsp;                 }  16&nbsp;                 done  17&nbsp;  18&nbsp;echo "Number of lines read = $Lines"     # 0  19&nbsp;                                         # Wrong!  20&nbsp;  21&nbsp;echo "------------------------"  22&nbsp;  23&nbsp;  24&nbsp;exec 3&#60;&#62; myfile.txt  25&nbsp;while read line &#60;&#38;3  26&nbsp;do {  27&nbsp;  echo "$line"  28&nbsp;  (( Lines++ ));                   #  Incremented values of this variable  29&nbsp;                                   #+ accessible outside loop.  30&nbsp;                                   #  No subshell, no problem.  31&nbsp;}  32&nbsp;done  33&nbsp;exec 3&#62;&#38;-  34&nbsp;  35&nbsp;echo "Number of lines read = $Lines"     # 8  36&nbsp;  37&nbsp;echo  38&nbsp;  39&nbsp;exit 0  40&nbsp;  41&nbsp;# Lines below not seen by script.  42&nbsp;  43&nbsp;$ cat myfile.txt  44&nbsp;  45&nbsp;Line 1.  46&nbsp;Line 2.  47&nbsp;Line 3.  48&nbsp;Line 4.  49&nbsp;Line 5.  50&nbsp;Line 6.  51&nbsp;Line 7.  52&nbsp;Line 8.</PRE></TD></TR></TABLE><HR></DIV></DIV></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN16482"HREF="io-redirection.html#AEN16482">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P><ANAME="FDREF1"></A>A <ICLASS="FIRSTTERM">file		 descriptor</I> is simply a number that		 the operating system assigns to an open file		 to keep track of it.  Consider it a simplified		 type of file pointer. It is analogous		 to a <ICLASS="FIRSTTERM">file handle</I> in		 <ICLASS="FIRSTTERM">C</I>.</P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN16494"HREF="io-redirection.html#AEN16494">[2]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>Using <TTCLASS="REPLACEABLE"><I>file	       descriptor 5</I></TT> might cause problems.	       When Bash creates a child process, as with <AHREF="internal.html#EXECREF">exec</A>, the child inherits	       fd 5 (see Chet Ramey's archived e-mail, <AHREF="http://www.geocrawler.com/archives/3/342/1996/1/0/1939805/"TARGET="_top">	       SUBJECT: RE:  File descriptor 5 is held open</A>).	       Best leave this particular fd alone.</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="here-docs.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="redircb.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Here Documents</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part5.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Redirecting Code Blocks</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

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