<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IGI&#039;s Blog &#187; Redirections</title>
	<atom:link href="http://www.igigo.net/archives/tag/redirections/feed" rel="self" type="application/rss+xml" />
	<link>http://www.igigo.net</link>
	<description></description>
	<lastBuildDate>Fri, 09 Dec 2011 04:19:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
	
<!-- Start Of Script Generated By WP-PostViews Plus -->
<script type='text/javascript' src='http://www.igigo.net/wp-includes/js/jquery/jquery.js?ver=1.4.2'></script>
<script type="text/javascript">
/* <![CDATA[ */
/* ]]> */
</script>
<!-- End Of Script Generated By WP-PostViews Plus -->
	<item>
		<title>bash重定向详解</title>
		<link>http://www.igigo.net/archives/79</link>
		<comments>http://www.igigo.net/archives/79#comments</comments>
		<pubDate>Wed, 23 Jun 2010 05:11:49 +0000</pubDate>
		<dc:creator>igi</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Redirections]]></category>

		<guid isPermaLink="false">http://www.igigo.net/?p=79</guid>
		<description><![CDATA[首先我们先回顾下bash现有的重定向符号 1.重定向输入输出，目标是文件word [n]&#60;word 默认n为0 [n]&#62;word 默认n为1 [n]&#62;&#124;word 默认n为1 noclobber选项有关，直接例子就明白它的用处了 [n]&#62;&#62;word 默认n为1 igi@igi-debian:~$ rm -f testfile igi@igi-debian:~$ touch testfile igi@igi-debian:~$ cat testfile igi@igi-debian:~$ set -o noclobber igi@igi-debian:~$ echo 2 &#62;testfile bash: testfile: cannot overwrite existing file igi@igi-debian:~$ echo 2 &#62;&#124; testfile igi@igi-debian:~$ cat testfile 2 2.重定向标准错误和标准输出到指定文件描述符 &#38;&#62;word 更通用 &#62;&#38;word &#62;word 2&#62;&#38;1 追加输出 &#38;&#62;&#62;word 没有&#62;&#62;&#38;word的表达方法 &#62;&#62;word 2&#62;&#38;1 [...]]]></description>
			<content:encoded><![CDATA[<p>首先我们先回顾下bash现有的重定向符号</p>
<h3>1.重定向输入输出，目标是文件word</h3>
<pre class="brush: plain; gutter: false; title: ;">
[n]&lt;word    默认n为0
[n]&gt;word    默认n为1
[n]&gt;|word   默认n为1    noclobber选项有关，直接例子就明白它的用处了
[n]&gt;&gt;word   默认n为1
</pre>
<pre class="brush: bash; title: ;">
igi@igi-debian:~$ rm -f testfile
igi@igi-debian:~$ touch testfile
igi@igi-debian:~$ cat testfile
igi@igi-debian:~$ set -o noclobber
igi@igi-debian:~$ echo 2 &gt;testfile
bash: testfile: cannot overwrite existing file
igi@igi-debian:~$ echo 2 &gt;| testfile
igi@igi-debian:~$ cat testfile
2
</pre>
<h3>2.重定向标准错误和标准输出到指定文件描述符</h3>
<pre class="brush: plain; gutter: false; title: ;">
&amp;&gt;word      更通用
&gt;&amp;word
&gt;word 2&gt;&amp;1
</pre>
<p>追加输出</p>
<pre class="brush: plain; gutter: false; title: ;">
&amp;&gt;&gt;word     没有&gt;&gt;&amp;word的表达方法
&gt;&gt;word 2&gt;&amp;1
</pre>
<h3>3.Here Documents</h3>
<pre class="brush: plain; gutter: false; title: ;">
 &lt;&lt;[-]word
   here-document
delimiter
-符号将删除所有行开头的tab符
</pre>
<h3>4.Here Strings</h3>
<pre class="brush: plain; gutter: false; title: ;">
&lt;&lt;&lt;word
</pre>
<h3>5.复制文件描述符</h3>
<pre class="brush: plain; gutter: false; title: ;">
[n]&lt;&amp;word   默认n为0，如果为数字，必须得为打开的文件描述符
[n]&lt;&amp;-      关闭文件描述符

[n]&gt;&amp;word   默认n为1，如果为数字，必须得为打开的文件描述符
[n]&gt;&amp;-      关闭文件描述符
</pre>
<h3>6.移动文件描述符</h3>
<pre class="brush: plain; gutter: false; title: ;">
[n]&lt;&amp;digit- 默认n为0
[n]&gt;&amp;digit- 默认n为1
</pre>
<h3>7.以读写方式打开文件描述符</h3>
<pre class="brush: plain; gutter: false; title: ;">
[n]&lt;&gt;word   文件不在时会被创建
</pre>
<p>如果要深刻理解重定向，先要明白以下2点<br />
1.shell(bash或者csh等)负责重定向，对于程序或者函数，这一切都是透明的，它只管输入输出，至于从哪输入哪输出，是shell解释器负责<br />
2.shell命令解析过程中，在实际执行命令前，IO重定向先设置好</p>
<p>我们来看以下的例子</p>
<h4>1.&#8217;echo 1 a1 >a2&#8242; 与 &#8216;echo 1 >a2 a1&#8242;</h4>
<pre class="brush: bash; title: ;">
igi@igi-debian:~$ echo 1 a1 &gt;a2
igi@igi-debian:~$ cat a2
1 a1
igi@igi-debian:~$ rm a2
igi@igi-debian:~$ echo 1 &gt;a2 a1
igi@igi-debian:~$ cat a2
1 a1
</pre>
<p>IO重定向是在命令执行前设置好，所以上面两种情况，最后的效果一样，bash先把输出重定向到a2文件，再执行&#8217;echo 1 a1&#8242;</p>
<h4>2.&#8217;ls nothisfile >res 2>&#038;1&#8242; 与 &#8216;ls nothisfile 2>&#038;1 >res&#8217;</h4>
<pre class="brush: bash; title: ;">
igi@igi-debian:~/rtest$ ls nothisfile
ls: cannot access nothisfile: No such file or directory
igi@igi-debian:~/rtest$ ls nothisfile &gt;res 2&gt;&amp;1
igi@igi-debian:~/rtest$ cat res
ls: cannot access nothisfile: No such file or directory
igi@igi-debian:~/rtest$ ls nothisfile 2&gt;&amp;1 &gt;res
ls: cannot access nothisfile: No such file or directory
igi@igi-debian:~/rtest$ cat res
igi@igi-debian:~/rtest$ ls -1
a
b
c
res
igi@igi-debian:~/rtest$ ls -1 2&gt;&amp;1 &gt;res
igi@igi-debian:~/rtest$ cat res
a
b
c
res
</pre>
<p>
&#8216;ls nothisfile >res 2>&#038;1&#8242;，文件描述符1被重定向到文件res(本来是标准输出)，然后再把文件描述符2重定向到文件描述符1(此时是文件描述符1指向文件res)，最后执行&#8221;ls nothisfile&#8221;，产生错误，被送往文件描述符2，最后流向文件res。<br />
&#8216;ls nothisfile 2>&#038;1 >res&#8217;，文件描述符2被重定向到文件描述符1(即标准输出：屏幕)，然后再把文件描述符1重定向到文件res，结果是文件描述符2被重定向到标准输出，文件描述符1被重定向到文件res，最后执行&#8221;ls nothisfile&#8221;产生的错误就被送往屏幕。
</p>
<h4>3.&#8217;ls nothisfile a >&#038;word&#8217; 与 &#8216;ls nothisfile a >&#038;123456&#8242;</h4>
<pre class="brush: bash; title: ;">
igi@igi-debian:~/test/shell$ ls -1
a
igi@igi-debian:~/test/shell$ cat a
this is a
igi@igi-debian:~/test/shell$ ls nothisfile a &gt;&amp;word
igi@igi-debian:~/test/shell$ cat word
ls: cannot access nothisfile: No such file or directory
a
igi@igi-debian:~/test/shell$ ls nothisfile a &gt;&amp;123456
-bash: 123456: Bad file descriptor
igi@igi-debian:~/test/shell$ cat 123456
cat: 123456: No such file or directory
</pre>
<p>
>&#038;这个重定向符号，在前面有提到，“重定向标准错误和标准输出到指定文件描述符“ 和 “复制文件描述符“ 都有这个符号, 实际上“重定向标准错误和标准输出到指定文件描述符“ 是 “复制文件描述符“ 的一种特别情况， 即当 [n]>&#038;word 的n省略 且  word不是数字时， 会重定向标准错误和标准输出 到指定文件。<br />
&#8220;ls nothisfile a >&#038;word&#8221; , 由于word不是纯数字， bash解析成 ”重定向标准错误和标准输出到指定文件描述符“， 效果相当于 &#8221; ls nothisfile a >word 2>&#038;1&#8243;<br />
&#8220;ls nothisfile a >&#038;123456&#8243;, 由于123456是纯数字， bash解析成 &#8220;复制文件描述符&#8221;, 相当于 &#8221; ls nothisfile a 1>&#038;123456&#8243; , 但由于 “ 复制文件描述符 “规定　“如果为数字，必须得为打开的文件描述符”<br />
所以发生了错误。
</p>
<h4>4.&#8217;ls a 1>&#038;-&#8217; 与 &#8216; ls a >&#038;1- &#8216;</h4>
<pre class="brush: bash; title: ;">
igi@igi-debian:~/test/shell$ ls
a
igi@igi-debian:~/test/shell$ cat a
this is a
igi@igi-debian:~/test/shell$ ls a &gt;&amp;1-
a
igi@igi-debian:~/test/shell$ ls a 1&gt;&amp;-
ls: write error: Bad file descriptor
</pre>
<p>
“  ls a >&#038;1- “，　>&#038;1-属于“移动文件描述符” 提到的 &#8220;[n]>&#038;digit-&#8221;, 用文件描述符digit替换掉文件描述符n, n描述符被关闭.n默认为1.  &#8220;ls a >&#038;1-&#8221;,  相当与 &#8221; ls a 1>&#038;1- &#8220;,  把文件描述符1替换掉原<br />
文件描述符1, 然后关闭原文件描述符1, 没发生变化, 输出依然被送到屏幕<br />
&#8221; ls a 1>&#038;- &#8220;,  >&#038;- 属于 &#8220;复制文件描述符&#8221; 提到的&#8221;关闭文件描述符&#8221;,  &#8221; ls a 1>&#038;- &#8220;, 关闭了文件描述符1, 在运行&#8221; ls a&#8221;, 由于输出默认都送到文件描述符1, 而它被关闭, 报&#8221;错误的文件描述符&#8221;
</p>
<h4>5.&#8217;ls a nothisfile 1>&#038;2-&#8217; 与 &#8216; ls a nothisfile 1<&#038;2- '</h4>
<pre class="brush: bash; title: ;">
igi@igi-debian:~/test/shell$ ls -1
a
igi@igi-debian:~/test/shell$ ls a nothisfile 1&lt;&amp;2-
a
igi@igi-debian:~/test/shell$ ls a nothisfile 1&gt;&amp;2-
a
igi@igi-debian:~/test/shell$ exec 3&lt;&gt;test
igi@igi-debian:~/test/shell$ ls a nothisfile 1&gt;&amp;3-
ls: cannot access nothisfile: No such file or directory
igi@igi-debian:~/test/shell$ cat test
a
igi@igi-debian:~/test/shell$
</pre>
<p>
&#8216; 1>&#038;2- &#8216; 与 &#8216; 1<&#038;2- ' 是一个效果的, [n]>&#038;digit- 和 [n]<&#038;digit-  这两个移动文件描述符的操作, 都是移动digit 到 n , 区别在n没有指定时, <&#038;digit- 等于 0<&#038;digit-,  而 >&#038;digit- 等于 1>&#038;digit-<br />
移动文件描述符, 就是把描诉符digit的指向给描述符n, 然后关了digit.  例子中的exec很好的解释移动文件描述符的行为, 文件描述符3被定向到文件test, 然后1>&#038;3-, 会使得1也定向到3所定向的文件test, 然后文件描诉符3被关闭, 效果就是标准输出被定向到test文件.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.igigo.net/archives/79/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

