Bash : IO 重定向
程序应该有数据的来源端、数据的目的端(输出结果的地方)已经报告问题的地方,它们分别被称为标准输入(standard input)、标准输出(standard output)以及标准错误输出(standard error)。程序不必知道也不用关心它的输入与输出背后是什么设备,当程序运行时,这些标准 IO 就已经打开并准备就绪了。
和 >> 符号把标准输出重定向到文件中 会覆盖掉已经存在的文件中的内容> 则把新的内容追加到已经存在的文件中的内容的尾部
$ : > log.txt
$ >> log.txt
$ >log.txt
$ >error.txt
$ &>log.txt
$ >log.txt >&
$ >log.txt >&
N&N &-???????????? # 关闭输出文件描述符 n&-,>&-??? # 关闭 stdout /dev/null 2>&1 和 2>&1 >/dev/null/dev/null 2>/dev/null/dev/null 2>&1 /dev/null/dev/null 的作用是将标准输出 1 重定向到 /dev/null 中,因此标准输出中的内容被完全丢弃了。 &1&1 用到了重定向绑定,采用 & 可以将两个输出绑定在一起,也就是说错误输出将会和标准输出输出到同一个地方。 Linux 在执行 shell 命令之前,就会确定好所有的输入输出位置,解释顺序为从左到右依次执行重定向操作。所以 >/dev/null 2>&1 的作用就是让标准输出重定向到 /dev/null 中,接下来因为错误输出的文件描述符 2 被重定向绑定到了标准输出的描述符 1,所以错误输出也被定向到了 /dev/null 中,错误输出同样也被丢弃了。 &1 >/dev/null&1 >/dev/null 执行的结果和 >/dev/null 2>&1 是不一样的!它的执行过程为:
#!/bin/E_FILE_ACCESS=<span style="color: #800080">70<span style="color: #000000">
E_WRONG_ARGS=<span style="color: #800080">71 <span style="color: #0000ff">if [ ! -r <span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">"<span style="color: #000000"> ] # 判断指定的输入文件是否可读 <span style="color: #0000ff">if [ -z <span style="color: #800000">"<span style="color: #800000">$2<span style="color: #800000">"<span style="color: #000000"> ] exec <span style="color: #800080">4<&<span style="color: #800080">0<span style="color: #000000"> # 保存默认 stdin exec <span style="color: #800080">7>&<span style="color: #800080">1<span style="color: #000000"> # 保存默认 stdout 假设输出文件是可写的-----------------------------------------------<span style="color: #0000ff">cat - | <span style="color: #0000ff">tr a-z A-<span style="color: #000000">Z # 转换为大写 从 stdin 中读取写到 stdout 上然而,stdin 和 stdout 都被重定向了-----------------------------------------------<span style="color: #000000">exec <span style="color: #800080">1>&<span style="color: #800080">7 <span style="color: #800080">7>&-<span style="color: #000000"> # 恢复 stout 恢复之后,下边这行代码将会如预期的一样打印到 stdout 上<span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">File "$1" written to "$2" as uppercase conversion.<span style="color: #800000">"<span style="color: #000000">
$ ./upper. .txt out.txt
myfile ><> myfile # 打开 myfile 并且将 fd -n <& -n . >&>&- # 关闭 fd
myfile # ==>
#!/bin/E_WRONG_ARGS=<span style="color: #800080">71
<span style="color: #0000ff">if [ -z <span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">"<span style="color: #000000"> ] <span style="color: #0000ff">then <span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">Usage: $0 input-file<span style="color: #800000">"<span style="color: #000000"> exit $E_WRONG_ARGS <span style="color: #0000ff">fi<span style="color: #000000"> Lines=<span style="color: #800080">0 <span style="color: #0000ff">cat <span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">" | <span style="color: #0000ff">while<span style="color: #000000"> read line; # 管道会产生子 shell 但是外部循环却不能访问} <span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">Number of lines read = $Lines<span style="color: #800000">" # <span style="color: #800080">0<span style="color: #000000"> 错误!<span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">------------------------<span style="color: #800000">"<span style="color: #000000"> 现在外部循环就可以访问了
}
$ ./avoid-subshell. .txt
#!/bin/E_WRONG_ARGS=<span style="color: #800080">71
<span style="color: #0000ff">if [ -z <span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">"<span style="color: #000000"> ] <span style="color: #0000ff">then <span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">Usage: $0 input-file<span style="color: #800000">"<span style="color: #000000"> exit $E_WRONG_ARGS <span style="color: #0000ff">fi<span style="color: #000000"> count=<span style="color: #800080">0 <span style="color: #0000ff">while [ <span style="color: #800000">"<span style="color: #800000">$name<span style="color: #800000">" !=<span style="color: #000000"> xxyy ]
$ ./whileblock. .txt
#!/bin/E_WRONG_ARGS=<span style="color: #800080">71
<span style="color: #0000ff">if [ -z <span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">"<span style="color: #000000"> ] <span style="color: #0000ff">then <span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">Usage: $0 input-file output-file<span style="color: #800000">"<span style="color: #000000"> exit $E_WRONG_ARGS <span style="color: #0000ff">fi <span style="color: #0000ff">if [ -z <span style="color: #800000">"<span style="color: #800000">$2<span style="color: #800000">"<span style="color: #000000"> ] FinalName=<span style="color: #800000">"<span style="color: #800000">xxyy<span style="color: #800000">"<span style="color: #000000"> <span style="color: #0000ff">for name <span style="color: #0000ff">in $(<span style="color: #0000ff">seq<span style="color: #000000"> $line_count)
$ ./forblock. .txt out.txt
/dev/null 2>&1 是什么鬼? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |