程序应该有数据的来源端、数据的目的端(输出结果的地方)已经报告问题的地方,它们分别被称为标准输入(standard input)、标准输出(standard output)以及标准错误输出(standard error)。程序不必知道也不用关心它的输入与输出背后是什么设备,当程序运行时,这些标准 IO 就已经打开并准备就绪了。
和 >> 符号把标准输出重定向到文件中 会覆盖掉已经存在的文件中的内容> 则把新的内容追加到已经存在的文件中的内容的尾部
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 是不一样的!它的执行过程为:
- &1,将错误输出绑定到标准输出上。由于此时的标准输出是默认值,也就是输出到屏幕,所以错误输出会输出到屏幕。
- /dev/null,将标准输出1重定向到 /dev/null 中。
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"> # 将写到输出文件中.
假设输出文件是可写的
-----------------------------------------------
<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
exec <span style="color: #800080">0<&<span style="color: #800080">4 <span style="color: #800080">4<&-<span style="color: #000000"> # 恢复 stdin
恢复之后,下边这行代码将会如预期的一样打印到 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
myfile
<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"> )); # 增加这个变量的值
但是外部循环却不能访问
}
<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">
错误!
<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"> )); # 增加这个变量的值
现在外部循环就可以访问了
# 没有子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
<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
<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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。