Bash   发布时间:2019-11-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Bash : IO 重定向大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

程序应该有数据的来源端、数据的目的端(输出结果的地方)已经报告问题的地方,它们分别被称为标准输入(standard input)标准输出(standard output)以及标准错误输出(standard error)。程序不必知道也不用关心它的输入与输出背后是什么设备,当程序运行时,这些标准 IO 就已经打开并准备就绪了。

@H_618_35@

和 >> 符号把标准输出重定向到文件中 会覆盖掉已经存在的文件中的内容> 则把新的内容追加到已经存在的文件中的内容的尾部

如下面的命令将会把文件 log.txt 变为一个空文件(就是 size 为 0):

$ : > log.txt

$ >> log.txt

$ >log.txt

$ >error.txt

$ &>log.txt

$ >log.txt >&

$ >log.txt >&

N默认为 1。&N默认为 1。

             # 关闭输入文件描述符 n&-             # 关闭输出文件描述符 n&-,>&-    # 关闭 stdout

@H_618_35@/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 是不一样的!它的执行过程为:

  1. &1,将错误输出绑定到标准输出上。由于此时的标准输出是默认值,也就是输出到屏幕,所以错误输出会输出到屏幕。
  2. /dev/null,将标准输出1重定向到 /dev/null 中。
@H_618_35@

ename 命令会将 stdin 重定向到文件中。 从这句开始,所有的 stdin 就都来自于这个文件了,而不是标准输入(通常都是键盘输入)。 这样就提供了一种按行读取文件的方法。当然,也可以用这种方法来重定向标准输出和标准错误输出。下面的 upper.sh 程序把输入文件中的字母转换为大写并输出到另外一个文件中,脚本中使用 exec 同时重定向了 stdin 和 stdout:

#!/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">then
<span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">Can't read from input file!<span style="color: #800000">"
<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_FILE_ACCESS
<span style="color: #0000ff">fi # 即使输入文件($<span style="color: #800080">1<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"> ]
<span style="color: #0000ff">then
<span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">Need to specify output file.<span style="color: #800000">"
<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: #000000">

exec <span style="color: #800080">4<&<span style="color: #800080">0<span style="color: #000000"> # 保存默认 stdin
exec < $<span style="color: #800080">1<span style="color: #000000"> # 将会从输入文件中读取.

exec <span style="color: #800080">7>&<span style="color: #800080">1<span style="color: #000000"> # 保存默认 stdout
exec > $<span style="color: #800080">2<span style="color: #000000"> # 将写到输出文件中.

@H_618_35@假设输出文件是可写的 @H_618_35@-----------------------------------------------

<span style="color: #0000ff">cat - | <span style="color: #0000ff">tr a-z A-<span style="color: #000000">Z # 转换为大写

@H_618_35@从 stdin 中读取 @H_618_35@写到 stdout 上 @H_618_35@然而,stdin 和 stdout 都被重定向了 @H_618_35@-----------------------------------------------<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
exec <span style="color: #800080">0<&<span style="color: #800080">4 <span style="color: #800080">4<&-<span style="color: #000000"> # 恢复 stdin

@H_618_35@恢复之后,下边这行代码将会如预期的一样打印到 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">
exit <span style="color: #800080">0

$ ./upper. .txt out.txt

title="Bash : IO 重定向" alt="Bash : IO 重定向" src="https://cn.js-code.com/res/2019/02-09/09/90e5ae533db89f6d96af8f8c56d4c028.png" >

还有一种稍微简单一些的方式把标准输入和标准输出重定向到文件:@myfile就创建它。如下面的 demo:

><> myfile # 打开 myfile 并且将 fd -n <& -n . >&>&- # 关闭 fd myfile # ==>

HellHell 中改变父 sHell 中变量的值。下面的 demo 通过 exec 重定向 IO 有效的规避了子 sHell 问题:

#!/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">do<span style="color: #000000"> {
<span style="color: #0000ff">echo<span style="color: #000000"> $line
(( Lines++<span style="color: #000000"> )); # 增加这个变量的值

@H_618_35@但是外部循环却不能访问

}
<span style="color: #0000ff">done

<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">

@H_618_35@错误!

<span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">------------------------<span style="color: #800000">"<span style="color: #000000">
exec <span style="color: #800080">3<> <span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">"
<span style="color: #0000ff">while read line <&<span style="color: #800080">3
<span style="color: #0000ff">do<span style="color: #000000"> {
<span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">$line<span style="color: #800000">"<span style="color: #000000">
(( Lines++<span style="color: #000000"> )); # 增加这个变量的值

@H_618_35@现在外部循环就可以访问了
#  没有子sHell,现在就没问题了

}
<span style="color: #0000ff">done<span style="color: #000000">
exec <span style="color: #800080">3>&-
<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: #000000">
exit <span style="color: #800080">0

Hell.sh 文件中,然后运行下面的命令:

$ ./avoid-subsHell. .txt

title="Bash : IO 重定向" alt="Bash : IO 重定向" src="https://cn.js-code.com/res/2019/02-09/09/ab3f23d3dbe2c823b5421798e6abd297.png" >

@H_618_35@

#!/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 ]
<span style="color: #0000ff">do<span style="color: #000000">
read name
<span style="color: #0000ff">if [ -z <span style="color: #800000">"<span style="color: #800000">$name<span style="color: #800000">" ]; <span style="color: #0000ff">then<span style="color: #000000">
break
<span style="color: #0000ff">fi
<span style="color: #0000ff">echo<span style="color: #000000"> $name
let <span style="color: #800000">"<span style="color: #800000">count += 1<span style="color: #800000">"
<span style="color: #0000ff">done <<span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">"
<span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">$count names read<span style="color: #800000">"<span style="color: #000000">
exit <span style="color: #800080">0

$ ./whileblock. .txt

title="Bash : IO 重定向" alt="Bash : IO 重定向" src="https://cn.js-code.com/res/2019/02-09/09/58e4e37cb322142edac76abd031d9782.png" >

#!/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"> ]
<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: #000000">

FinalName=<span style="color: #800000">"<span style="color: #800000">xxyy<span style="color: #800000">"<span style="color: #000000">
line_count=$(<span style="color: #0000ff">wc <span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">" | <span style="color: #0000ff">awk <span style="color: #800000">'<span style="color: #800000">{ print $1 }<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)
<span style="color: #0000ff">do<span style="color: #000000">
read name
<span style="color: #0000ff">echo <span style="color: #800000">"<span style="color: #800000">$name<span style="color: #800000">"
<span style="color: #0000ff">if [ <span style="color: #800000">"<span style="color: #800000">$name<span style="color: #800000">" = <span style="color: #800000">"<span style="color: #800000">$FinalName<span style="color: #800000">"<span style="color: #000000"> ]
<span style="color: #0000ff">then<span style="color: #000000">
break
<span style="color: #0000ff">fi
<span style="color: #0000ff">done < <span style="color: #800000">"<span style="color: #800000">$1<span style="color: #800000">" > <span style="color: #800000">"<span style="color: #800000">$2<span style="color: #800000">"<span style="color: #000000">
exit <span style="color: #800080">0

$ ./forblock. .txt out.txt
@H_618_35@

考:/dev/null 2>&1 是什么鬼?

大佬总结

以上是大佬教程为你收集整理的Bash : IO 重定向全部内容,希望文章能够帮你解决Bash : IO 重定向所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: