Prayer

在一般中寻求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

关于>&2、2>&1等重定向的详细解释

Posted on 2009-06-05 20:50 Prayer 阅读(243) 评论(0)  编辑 收藏 引用 所属分类: Shell
在POSIX shell中,命令的结果可以通过%>;的形式来定义(其中%表示文件描述符:1为标准输出stdout、2为标准错误stderr)!系统默认%值是1,也就是1>;,而1>;可以简写为>;,也就是默认为>;。而stdout的默认目标是终端(这点不用验证吧)。另外,stderr的默认目标我个人认为也是终端,比如:
#abcddcba
sh: abcddcba: not found.
错误信息显示在终端上(对于telnet、dtterm等,那就说虚拟终端了)。

==============实验环境==============
#mkdir redtest
#cd redtest
#mkdir a4
#touch a1 a2 a3 

==============简单试验==============
#ls >;redout.lst (等同于ls 1>;redout.lst,标准输出重定向)
系统先执行>;redout.lst,生成一个空文件,然后系统执行ls,再把结果重定向到redout.lst。这时在终端看不到任何信息,但是#more redout.lst可以看到a1、a2、a3、a4和redout.lst。
#./ourgame 2>;rederr.lst (标准错误重定向)
因为系统找不到执行脚本ourgame,产生错误,但并不是显示在终端上,而是把错误信息重定向到了rederr.lst。
#more rederr.lst
sh: ourgame: not found.
==============组合试验==============
#rm rederr.lst
#rm redout.lst
#vi conj
#!/usr/bin/sh
#Email:webmaster@myhpux.com
for FN in `ls`
do
if [[ -f $FN ]]
then
echo $FN
else
cp $FN $FN.new
fi
done
//conj的作用是执行以后产生标准输出(echo)和标准错误(cp)
#chmod 755 conj
看看一下命令的结果:
#./conj 
a1 //stdout
a2 //stdout
a3 //stdout
cp: a4: is a directory. Need "-R" option.//stderr
conj //stdout
再试试重定向的结果:
(1)、输出重定向到文件a1,终端上只能看到标准错误:
#./conj >;a1
#./conj 1>;a1
#more a1 
a1
a2
a3
conj
(2)、错误重定向到文件a1,终端上只能看到标准输出:
#./conj 2>;a1
#more a1
cp: a4: is a directory. Need "-R" option.
(3)、把标准输出和标准错误都重定向到a1,终端上看不到任何信息:
#./conf >;a1 2>;&1 (等同于#./conf 1>;a1 2>;&1)
#more a1
a1
a2
a3
cp: a4: is a directory. Need "-R" option.
conj
//其中&的意思,可以看成是“The same as”、“与...一样”的意思。本例中就是2>;和1>;一样,都输出到a1中。
再看一个例子:
#./conj 2>;&1 >;a1
同样可以解释为2>;和1>;一样,但是这时1>;是系统默认输出到终端,所以标准错误也输出到终端;然后,系统把标准输出重定向到文件a1。

记得unixpianpianMM有个问题:
echo "Usage $0 -d" >;&2
那么可以解释为echo "Usage $0 -d" 1>;&2
也就是把结果输出到和标准错误一样;之前如果有定义标准错误重定向到某log文件,那么标准输出也重定向到这个log文件。

以上脚本在HP-UX11.00 L2000通过!所有定义、名词均建立在本人的实践和本人所了解的知识上,如有错误,请指正,谢谢!!!





 wangrujun 回复于:2002-11-23 09:39:08

经典!


 playboy 回复于:2003-03-03 20:11:39

Bourne和Korn shell中的重定向
从文件输入                                                       <file or 0<file
将标准输出重定向为文件                                    >;file or 1>;file
将标准错误重定向为文件                                     2>;file
将标准输出追加到文件                                        >;>;file
将标准错误重定向为标准输入                              2>;&amp;1
将第一个命令的输入作为第二个文件的输入          cmd1|cmd2
将第一个文件即作为标准输入也作为标准输出       <>;file
关闭标准输入                                                    0<&amp;-
关闭标准输出                                                    1>;&amp;-
关闭标准错误                                                    2>;&amp;-


 uman 回复于:2003-03-05 01:30:05

"stderr的默认目标我个人认为也是终端"
就是这样的,而且是unbuffered.


 yhuang95411 回复于:2004-03-04 02:27:55

:mrgreen:  :mrgreen:  :mrgreen:  :mrgreen:  :mrgreen: 
但是缺乏比如说
2>;&3, 1>;&3, 3>;1&, 3>;&2
的解释

谁能补全???


 wingger 回复于:2004-11-14 14:00:43

引用:#./conj 2>;&1 >;a1 
同样可以解释为2>;和1>;一样,但是这时1>;是系统默认输出到终端,所以标准错误也输出到终端;然后,系统把标准输出重定向到文件a1。 

记得unixpianpianMM有个问题: 
echo "Usage $0 -d" >;&2 
那么可以解释为echo "Usage $0 -d" 1>;&2 
也就是把结果输出到和标准错误一样;之前如果有定义标准错误重定向到某log文件,那么标准输出也重定向到这个log文件。

 

引用:原帖由 "网中人" 发表:
$
 ls my.file no.such.file 1>;file.both 2>;file.both 
从 file system 的角度来说,单一档案在单一时间内,只能被单一的 FD 作写入。 
假如 stdout(1) 与 stderr(2) 都同时在写入 file.both 的话, 
则要看它们在写入时否碰到同时竞争的情形了,基本上是"先抢先赢"的原则。 
让我们用周星驰式的"慢镜头"来看一下 stdout 与 stderr 同时写入 file.out 的情形好了: 
* 第 1, 2, 3 秒为 stdout 写入 
* 第 3, 4, 5 秒为 stderr 写入 
那么,这时候 stderr 的第 3 秒所写的数据就丢失掉了﹗

 
要是我们能控制 stderr 必须等 stdout 写完再写,或倒过来,stdout 等 stderr 写完再写,那问题就能解决。 
但从技术上,较难掌控的,尤其是 FD 在作"长期性"的写入时... 

那,如何解决呢?所谓山不转路转、路不转人转嘛, 
我们可以换一个思维:将 stderr 导进 stdout 或将 stdout 导进 sterr ,而不是大家在抢同一份档案,不就行了﹗ 
bingo﹗就是这样啦: 

* 2>;&1 就是将 stderr 并进 stdout 作输出 
* 1>;&2 或 >;&2 就是将 stdout 并进 stderr 作输出 

于是,前面的错误操作可以改为: 

$ ls my.file no.such.file 1>;file.both 2>;&1 
或 
$ ls my.file no.such.file 2>;file.both >;&2
 

这样,不就皆大欢喜了吗? 呵~~~ ^_^



 wingger 回复于:2004-11-14 14:19:07

引用:原帖由 "yhuang95411" 发表:
:mrgreen:  :mrgreen:  :mrgreen:  :mrgreen:  :mrgreen: 
但是缺乏比如说
2>;&3, 1>;&3, 3>;1&, 3>;&2
的解释

谁能补全???




command <&m 把文件描述符m作为标准输入 
command >;&m 把标准输出重定向到文件描述符m中 
command <&- 关闭标准输入


 safirst 回复于:2005-07-29 20:28:01

全了!呵呵


 lei8c8 回复于:2005-07-29 20:33:24

顶!


 yjtech 回复于:2005-07-30 22:04:35

[URL=http://www.linky.com.cn]益久联合网:提供免费网站链接,网站链接,链接网,免费链接网,友情链接,网络营销,网络推广[/URL]
[URL=http://www.yecaomei.com]野草莓:文化休闲网站 文化,休闲[/URL]
[URL=http://www.hiday.com.cn]www.hiday.com.cn[/URL]
[URL=http://www.webusiness.cn]益久网赢:专业的网络营销顾问服务,为您提供一站式网络营销顾问服务以及网站设计与网络技术支持:网站制作,建站程序,网页设计,网络营销,网络推广,网络营销顾问服务[/URL]
[URL=http://www.taodongdong.com]www.taodongdong.com[/URL]


 想飞的青蛙 回复于:2005-08-31 19:15:27

晕!居然还有这样的贴子!


 yttlovezxx 回复于:2005-09-14 23:27:22

如果谈到 I/O 重定向,就涉及到文件标识符 (File Descriptor) 的概念, 在 Linux 系统中,系统为每一个打开的文件指定一个文件标识符以便系统对文件进行跟踪,这里有些和C语言编程里的文件句柄相似,文件标识符是一个数字,不同数字代表不同的含义,默认情况下,系统占用了 3 个,分别是0标准输入(stdin),1 标准输出 (stdout), 2 标准错误 (stderr), 另外 3-9 是保留的标识符,可以把这些标识符指定成标准输入,输出或者错误作为临时连接。通常这样可以解决很多复杂的重定向请求。



 net_robber 回复于:2006-08-31 14:08:30

今天回头补课#(:


 欣雨尘香 回复于:2007-09-26 11:45:23

受益:)


 shkjb 回复于:2007-09-27 16:38:06

顶!


 冰冰河 回复于:2007-10-23 16:26:09

“The same as”   看到一种说法是 重定向输入操作符 (<)  复制操作符 (&)  不知道那种是正确的


 liaosnet 回复于:2007-10-23 17:16:20

这个是不是该转到SHELL里去哦?~


 Guanqun 回复于:2008-06-16 16:51:31

http://qun.wp-host.cn/?p=92写了点重定向的小结,欢迎访问,讨论。


 by325 回复于:2008-07-03 00:03:45

真是超强帖啊,受益了,谢谢楼主了


 ourangdegushi 回复于:2008-08-07 23:30:52

闷在心里好久的问题,终于明了啦,万分感谢啊


 clement1986 回复于:2008-12-24 10:43:10

其实一般用的时候就是形式上的把2>1&加在后面就行


 prot 回复于:2009-02-27 10:57:31

MARK


 noexcuse 回复于:2009-04-25 19:10:08

>;是怎么回事?
为什么我用ls >;a.txt的语句,在Solaris下根本就跑不通?
thx

[ 本帖最后由 noexcuse 于 2009-4-25 19:12 编辑 ]




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=16361
转载请注明作者名及原文出处

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理