我是shell脚本的新手,我使用的是Ubuntu 11.10。 在terminal使用exec 1>file
命令后,无论我给terminal的命令是什么,它的输出都不会显示在terminal上。 我知道STDOUT被redirect到文件,这些命令的输出被redirect到文件。
我的问题在这里
一旦我使用exec 1>file
,我该如何摆脱这个? 即如何停止STDOUTredirect到文件并恢复STDOUT的正常操作(即redirect到terminal,而不是文件)?
我尝试使用exec 1>&-
但它不起作用,因为这closures了STDOUT文件描述符。
请详细介绍exec 1>file
和exec 1>&-
全部操作,
如果我们使用exec 0>&-
exec 1>&-
exec 2>&-
closures标准文件描述符0,1,2,会发生什么?
在执行初始exec
之前,您必须为恢复做好准备:
exec 3>&1 1>file
稍后恢复原始标准输出:
exec 1>&3 3>&-
第一个exec
将原始文件描述符1(标准输出)复制到文件描述符3,然后将标准输出重定向到指定的文件。 第二个exec
再次将文件描述符3复制到标准输出,然后关闭文件描述符3。
这有点开放。 它可以在C代码级别或shell命令行级别进行描述。
exec 1>file
只需将shell的标准输出(1)重定向到指定的文件即可。 文件描述符现在引用指定的文件; 写入标准输出的任何输出都将转到该文件。 (请注意,交互式shell中的提示会写入标准错误,而不是标准输出。)
exec 1>&-
只需关闭shell的标准输出。 现在没有标准输出的打开文件。 如果程序运行时没有标准输出,程序可能会感到不安。
如果关闭标准输入,标准输出和标准错误的全部三个,交互式shell将在关闭标准输入时退出(因为在读取下一个命令时将会收到EOF)。 一个shell脚本将继续运行,但它运行的程序可能会感到不安,因为它们保证了3个打开的文件通道 – 标准输入,标准输出,标准错误 – 当你的shell运行它们,如果没有其他的I / O重定向,那么他们没有得到他们承诺的文件通道,所有的地狱都可能破裂(唯一的方法就是你知道命令的退出状态可能不会是零 – 成功)。
问题1 :有一个简单的方法可以在将终端重定向到一个文件后将stdout恢复到终端:
exec >/dev/tty
虽然保存原始的stdout文件描述符通常需要稍后恢复,在这种情况下,您希望stdout
是/dev/tty
因此不需要做更多的事情。
$ date Mon Aug 25 10:06:46 CEST 2014 $ exec > /tmp/foo $ date $ exec > /dev/tty $ date Mon Aug 25 10:07:24 CEST 2014 $ ls -l /tmp/foo -rw-r--r-- 1 jlliagre jlliagre 30 Aug 25 10:07 /tmp/foo $ cat /tmp/foo Mon Aug 25 10:07:05 CEST 2014
问题2 : exec 1>file
是一个稍微更详细的方式做exec >file
,如前所述,重定向标准输出到给定的文件,只要你有权创建/写入它。 如果该文件不存在,则会创建该文件,如果该文件被截断,则会被截断。
exec 1>&-
正在关闭标准输出,在大多数情况下这可能是一个坏主意。
Q3 :命令应该是
exec 0<&- exec 1>&- exec 2>&-
请注意stdin的反向重定向。
可能会这样简化:
exec <&- >&- 2>&-
这个命令关闭所有三个标准文件描述符。 这是一个非常糟糕的主意。 如果你想要一个脚本从这些渠道断开,我会建议这个更强大的方法:
exec </dev/null >/dev/null 2>&1
在这种情况下,所有的输出将被丢弃,而不是触发错误,所有的输入将只返回任何东西,而不是失败。
虽然我完全同意Jonathan的Q1,但有些系统具有/dev/stdout
,所以你可能可以执行exec 1>file; ...; exec 1>/dev/stdout
exec 1>file; ...; exec 1>/dev/stdout
接受的答案对我来说太冗长了。 所以,我决定总结一下你原来的答案。
exec 1> ./output.test.txt echo -e "First Line: Hello World!" printf "%s\n" "2nd Line: Hello Earth!" "3rd Line: Hello Solar System!" # This is uneccessary, but # it stops or closes stdout. # exec 1>&- # Send stdout back to stdin exec 1>&0 # Oops... I need to append some more data. # So, lets append to the file. exec 1>> ./output.test.txt echo -e "# Appended this line and the next line is empty.\n" # Send stdout back to stdin exec 1>&0 # Output the contents to stdout cat ./output.test.txt
Bourne,Bash,tcsh,Linux,BSD,AIX,HP,Busybox,Toybox等中的IO重定向还有here-docs,here-strings和process-substitution。