bash 中的 exec 重定向

bash 中的 exec 重定向

我编写了很多非交互式脚本,我希望所有输出都转到日志文件,并且屏幕上不显示任何内容。

为了解决这个问题,我一直在使用:

#!/bin/bash

exec &> logfile
echo "Step One:"
/some/command/one
echo "Step Two:"
/some/command/two

我想确保这是一个明智的方法。

如果我继续使用这种方法,是否会遇到任何重大缺点或问题?如果是这样,它们是什么以及如何最好地减轻它们(包括通过改变我的方法)。

答案1

将命令输出重定向到日志文件

将所有命令输出(包括错误消息)重定向到日志文件是非交互式 shell 脚本的标准做法。记录由 cron 运行或由其他外部事件触发的脚本的命令输出尤其有用,并且在此类用例中没有任何缺点。

我的许多 shell 脚本在开头附近都包含以下几行:

exec 1>>"$logfile"
exec 2>&1

这些重定向命令的顺序很重要。第一个exec命令将所有写入重定向到stdout(1) 流以追加 ( >>) 到日志文件。第二个命令将对 (2) 流的所有写入重定向到(1) 当前指向的stderr同一文件描述符。stdout仅使用一个文件描述符来访问文件可确保写入按所需顺序发生。

如果使用 Bash,您可以将这些命令组合成一个执行相同操作的结构:

exec &>>"$logfile"

如果您希望每次运行脚本时清除日志文件中以前的条目,请仅使用单个>重定向运算符(覆盖以前的内容):

exec &>"$logfile"

使用exec内置函数进行输入/输出重定向是由 POSIX 定义指定的外壳命令语言,并且 exec内置函数可在任何 POSIX 兼容 shell 中使用。

运行交互式 shell 时重定向

您可以在临时/一次性交互式 shell 会话中尝试将标准输出重定向到文件。运行后exec 1>outfile,所有未来的命令都会将其输出打印到outfile终端而不是终端。

您还可以尝试在交互式 shell 会话中重定向标准错误,但这可能会使交互式 shell 会话非常难以使用。

运行后exec 2>errorfile,任何其他命令产生的标准错误都会按预期写入重定向的错误文件。然而,问题是今后,shell(在本例中为 Bash)将其提示打印到此文件,并且作为命令键入的任何文本也会重定向到此文件。某些 shell(例如 Bash)也会回显 to 接收到的stdin字符stderr。在其他情况下,例如dash,对于 shell 会话的其余部分,您基本上是在盲目工作,因为根本没有任何内容发送到终端。这显然使得非常困难继续与 shell 交互。

作为猎户座指出斯科特说,您可以在分别使用和尝试任何此类实验之前存储对默认描述符stdout和文件描述符的引用 。完成实验后,您可以通过运行将打印恢复为标准错误, 并将打印恢复为标准输出。stderrexec 3>&1exec 4>&2exec 2>&4exec 1>&3

对于交互式使用,我建议在逐个命令的基础上重定向标准输出和标准错误流: .>> outfile 2>&1 command with arguments

相关内容