shell中>&2的含义及用法

在阅读《Shell脚本学习指南》时,看到这么一段代码

if [ -f "$file" ] && ! [ -w "$file" ]
then
    # $file存在且为一般文件,但不可写入
    echo $0: $file is not writable, giving up. >&2
    exit 1
fi
但是对>&2的含义不是很明白,于是就上网查了一下,整理如下


来自 http://bbs.chinaunix.net/thread-1702116-1-1.html sayigood

>&2 

也就是把结果输出到和标准错误一样;之前如果有定义标准错误重定向到某file文件,那么标准输出也重定向到这个file文件。
其中&的意思,可以看成是“The same as”、“与...一样”的意思


来自 http://www.360doc.com/content/13/0523/16/7044580_287544243.shtml#

shell上:
0表示标准输入
1表示标准输出
2表示标准错误输出
> 默认为标准输出重定向,与 1> 相同
2>&1 意思是把 标准错误输出 重定向到 标准输出.
&>file 意思是把 标准输出 和 标准错误输出 都重定向到文件file中

用例子说话:

1. grep da * 1>&2 
2. rm -f $(find / -name core) &> /dev/null
上面两例中的 & 如何理解,&不是放到后台执行吗?

牛解:
1.&>file或n>&m均是一个独立的重定向符号,不要分开来理解。
2.明确文件和文件描述符的区别。
3.&>file表示重定向标准输出和错误到文件
例如:
rm -f $(find / -name core) &> /dev/null,/dev/null是一个文件,这个文件比较特殊,所有传给它的东西它都丢弃掉。
4.n>&m表示使文件描述符n成为输出文件描述符m的副本。这样做的好处是,有的时候你查找文件的时候很容易产生无用的信息,如:2> /dev/null的作用就是不显示标准错误输出;另外当你运行某些命令的时候,出错信息也许很重要,便于你检查是哪出了毛病,如:2>&1
例如:
注意,为了方便理解,必须设置一个环境使得执行grep da *命令会有正常输出和错误输出,然后分别使用下面的命令生成三个文件:
grep da * > greplog1
grep da * > greplog2 1>&2   
grep da * > greplog3 2>&1  //grep da * 2> greplog4 1>&2 结果一样
#查看greplog1会发现里面只有正常输出内容
#查看greplog2会发现里面什么都没有

#查看greplog3会发现里面既有正常输出内容又有错误输出内容


来自 http://bbs.chinaunix.net/thread-433972-1-1.html

在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:[email protected]
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>a1

看看这篇文章就知道答案了http://blog.chinaunix.net/uid-560601-id-2735912.html

正确的做法应该是:

#./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。



你可能感兴趣的:(Linux,Shell,shell,linux)