I/O重定向

Linux Shell 环境中支持输入输出重定向,用符号<和>来表示。0、1和2分别表示标准输入、标准输出和标准错误信息输出,可以用来指定需要重定向的标准输 入或输出,比如 2>a.txt 表示将错误信息输出到文件a.txt中。

同时,还可以在这三个标准输入输出之间实现重定向,比如将错误信息重定向到标准输出,可以用 2>&1来实现

Linux下还有一个特殊的文件/dev/null,它就像一个无底洞,所有重定向到它的信息都会消失得无影无踪。这一点非常有用,当我们不需要回 显程序的所有信息时,就可以将输出重定向到/dev/null。

如果想要正常输出和错误信息都不显示,则要把标准输出和标准错误都重定向到/dev/null, 例如:

# ls 1>/dev/null 2>/dev/null

还有一种做法是将错误重定向到标准输出,然后再重定向到 /dev/null,例如:

# ls >/dev/null 2>&1

注意:此处的顺序不能更改,否则达不到想要的效果,此时先将标准输出重定向到 /dev/null,然后将标准错误重定向到标准输出,由于标准输出已经重定向到了/dev/null,因此标准错误也会重定向到/dev/null,于 是一切静悄悄

 

 

 

____________________________________________________________

用过Unix的恐怕没有不知道I/O重定向的,ls>a.txt就是一个I/O重定向。所谓I/O重定向,简单的理解就是透明的改变命令预定 的输入源或输出目的地,像ls>a.txt就是把输出目的地改成了a.txt而不是预定的stdout.

 

要想理解好I/O重定向,就不能不对Unix的文件描述符(File Descriptor)有所了解。文件描述符的概念和在C语言里的操作,这里不再赘述了,资料很多。此处只说说Shell里的重定向。

 

输出重定向

 

格式[n]>word

Shell先对word进行各种扩展(花括号、波浪号、变量扩展等,详见Shell命令中的扩展和替换 ),将最后扩展的结果作为一个文件。Shell打开这个文件并在内部将新得到的文件描述符复制到n。n如果省略则默认为1

>和>>的区别在于,使用前者,Shell会创建新文件,如果文件已经存在,原来的内容会被清空。后者要文件必须存在,在文件后 面添加内容

 

输入重定向

  格式[n]<word

Shell先对word进行各种扩展(花括号、波浪号、变量扩展等,详见Shell命令中的扩展和替换 ),将最后扩展的结果作为一个文件。Shell打开这个文件并在内部将新得到的文件描述符复制到n。n如果省略则默认为0,也就是标准输入。

 

同时重定向标准错误和标准输出

格式:&>word或>&word,推荐第一种。shell支持对word的扩展,且word扩展后作为一个文件名。 相当于:
>word 2>&1

Here Documen t: 把下面一段代码重定向到命令的标准输入。
格式 <<[-] word
        here-document
    delimiter

delimiter是一个结束指示器,相当于我们在控制台输入的ctrl+D。
Shell不对word进行任何扩展。

Shell代码
  1. [jjz@localhost test]$ abc=hello  
  2. [jjz@localhost test]$ cat <<$abc  
  3. > this is here document  
  4. > hello            这 里并未停止,shell不对$abc进行扩展,结束符是$abc而不是hello  
  5. > $abc  
  6. this is here document  
  7. hello  
[jjz@localhost test]$ abc=hello
[jjz@localhost test]$ cat <<$abc
> this is here document
> hello            这里并未停止,shell不对$abc进行扩展,结束符是$abc而不是hello
> $abc
this is here document
hello
 

如果word是引号括起来的,delimiter为word去除所有的引号后字符串,不对here-document进行扩展。

Shell代码
  1. [jjz@localhost test]$ cat << "DONE"  
  2. > $abc  
  3. DONE  
  4. $abc    DONE 两边有引号,因此没有对abc进行扩展  
[jjz@localhost test]$ cat << "DONE"
> $abc
> DONE
$abc    DONE两边有引号,因此没有对abc进行扩展
 

如果word没有引号,对here-document进行扩展。

Shell代码
  1. [jjz@localhost test]$ cat << DONE  
  2. > $abc  
  3. > DONE  
  4. hello    对 abc进行了扩展  
[jjz@localhost test]$ cat << DONE
> $abc
> DONE
hello    对abc进行了扩展
 

如果写了-,则输出是所有的引导tab都去除.

还有一种<<<word,对word扩展并作为命令的标准输入

 

复制文件描述符
输入:格式 [n]<&word。

这个功能和直接在c里面调用dup2()差不多,很好很强大。

word扩展之后应该得到一个数字。shell得到word所指定的输入描述符的一个copy,并设定为n。如果word所制定的数字不是一个有效 地输入描述符,会出错。如果word得到的结果是 -,则输入被关闭。n默认为0.复制输出描述符也是这样的。

输出:格式 [n]>&word。

和上面差不多,只不过这个是复制输出描述符。

word扩展之后应该得到一个数字。shell得到word所指定的输入描述符的一个copy,并设定为n。如果word所制定的数字不是一个有效 地输出描述符,会出错。如果word得到的结果是 -,则输入被关闭。n默认为0.复制输出描述符也是这样的。


移动输出描述符
输入:形式 [n]<&digit-

移动文件描述符digit到n。支持对digit的扩展。

基本上就是先copy到n再关闭digit。

输出:形式 [n]>&digit-

和上面相似,不过是针对输出的

 

注: 虽然上面说复制和移动文件描述符是要注意输入和输出的区别,不过根据我的尝试,复制和移动文件描述符时,shell不会判断文件描述符是输入还是输出(因 为dup2不判断……),所以照样可以用1(标准输出)<&x,把输出的文件描述符x复制到1,不是只能使用1>&x

 

其他

  1. 为读写打开: [n]<>word.
  2. 重定向处理顺序:左到右。
    有的时候要注意重定向的顺序,否则可能会不正确
  3. exec 可以使用指定的描述符打开一个文件(可以配合复制、移动文件描述符使用)
    exec 0<test.txt   以只读方式打开文件test.txt,使用文件描述符0
    exec 1>test.txt   以只写方式打开文件test.txt,使用文件描述符1,这样后面的命令的输出全部到了test.txt里
    exec 1<&-           关闭文件描述符1,这样后面命令的输出全没了

  4. 几个特殊的文件名
    • /dev/fd/n,n是一个有效正整数,引用文件描述符n。
    • /dev/stdin
    • /dev/stdout
    • /dev/stderr
    • /dev/tcp/host/port 打开并进行socket传输
    • /dev/udp/host/port 打开并进行socket传输

转载于:https://my.oschina.net/alphajay/blog/7735

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值