如何在bash中停止重定向


8

我用 :

exec >script.log 2>&1

在我的脚本中将所有输出重定向到文件。在脚本末尾,我想在屏幕上打印一条消息。如何停止重定向?

Answers:


12

您可以exec再次调用以恢复原始描述符。您需要将它们保存在某个地方。

exec 3>&1 4>&2 1>script.log 2>&1
 logged portion 
exec 1>&3 2>&4
echo >&2 "Done"

在记录的部分内,您可以通过重定向到额外的描述符来将原始描述符用于一个命令。

echo "30 seconds remaining" >&3

或者,您可以将脚本的记录部分放入复合命令中,然后重定向该复合命令。如果您想在重定向部分内某个地方的陷阱中使用原始描述符,则此方法不起作用。

{
 logged portion 
} >script.log 2>&1
echo >&2 "Done"

关于回声的评论>&3使之成为我的首选解决方案。再次感谢)!
威廉

6

对stdout和stderr使用附加的fd 3和4,并在脚本末尾将1和2重定向到它们:

exec 3>&1 4>&2
exec >script.log 2>&1

echo "Some code"

exec >&3 2>&4
echo "Done"

这将返回错误:exec 3>/dev/stdout 4>/dev/stderr -bash: /dev/stdout: Permission denied
Willem 2013年

当您尝试在另一个用户中启动脚本时,可能会发生此错误。您是否通过sudo使用脚本?
2013年

是的,就是这样:我对另一个帐户执行了su并运行了代码。我正在编写的脚本将通过sudo运行,因此在那里我将遇到相同的问题。还有其他选择吗?
威廉

我相信有一些优雅的解决方案,不幸的是,我知道唯一的选择,从安全角度来看,这可能是绝对不能接受的:将目标用户添加到初始用户主要组中,并为/ proc / self / fd / 1添加组写权限在脚本启动之前。(甚至更容易受到攻击-只需对所有人都授予临时写许可权,并在脚本完成后无需进行组更改就将其删除)。

1
@Willem通过使用文件描述符而不是重新打开文件,可以轻松解决此问题,请参见我的编辑。
吉尔斯(Gillles)“所以-别再邪恶了”

1

首先,您应该检查一下是否有tty。

if tty -s; then
    echo "Hello, World" > $(tty)
fi

1
请注意,这种方式无法将输出提供给外部程序。
匆匆

不必使用外部tty实用程序。您可以重定向到特殊设备/dev/tty
暂停,直到另行通知。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.