我想运行几个命令,并将所有输出捕获到一个日志文件中。我还想将任何错误打印到屏幕上(或者可选地将输出发送给某人)。
下面是一个例子。下面的命令将运行三个命令,并将所有输出(STDOUT和STDERR)写入一个日志文件。
{ command1 && command2 && command3 ; } > logfile.log 2>&1下面是我想对这些命令的输出所做的事情:
我遇到的问题是STDERR在I/O重定向过程中丢失了上下文。“2>&1”将将STDERR转换为STDOUT,因此,如果执行2> error.log,则无法查看错误
以下是几个更好的例子。让我们假设我正在运行一些熟悉的构建命令,但我不希望整个构建仅仅因为一个错误而停止,所以我使用了“--持续”标志。
{ ./configure && make --keep-going && make install ; } > build.log 2>&1或者,这里有一个简单的(也可能是草率的)构建和部署脚本,如果出现错误,它将继续运行。
{ ./configure && make --keep-going && make install && rsync -av --keep-going /foo devhost:/foo} > build-and-deploy.log 2>&1我想我想要的是某种Bash I/O重定向,但我不明白。
发布于 2010-05-20 06:00:50
(./doit >> log) 2>&1 | tee -a log这将获取stdout并将其附加到日志文件中。
然后,stderr将被转换为stdout,该stdout被管道传输到tee,后者将其附加到日志中(如果您有Bash 4,您可以用|&替换2>&1 | ),并将它发送到stdout,stdout将出现在tty上,或者可以通过管道传输到另一个命令。
我对这两种方式都使用了追加模式,这样无论shell重定向和tee打开文件的顺序如何,您都不会将原始文件吹走。也就是说,stderr/stdout可能以一种意想不到的方式交织在一起。
发布于 2010-05-20 06:26:04
如果您的系统有/dev/fd/*节点,您可以这样做:
( exec 5>logfile.txt ; { command1 && command2 && command3 ;} 2>&1 >&5 | tee /dev/fd/5 )这将打开日志文件的文件描述符5。执行指向标准输出的标准错误的命令、指向fd 5的标准输出和将输出复制到fd 5(日志文件)的管道stdout (现在只包含stderr)。
发布于 2013-08-01 03:44:17
下面是如何运行一个或多个命令,按照生成它们的顺序将标准输出和错误捕获到日志文件,并在任何您喜欢的终端屏幕上只显示标准错误。在linux上使用bash。可能在大多数其他环境中都能工作。我将用一个例子来说明它是如何完成的。
预告片:
打开两个窗口(shell、tmux会话等)
我将用一些测试文件演示,因此创建测试文件:
touch /tmp/foo /tmp/foo1 /tmp/foo2在window1中:
mkfifo /tmp/fifo
0</tmp/fifo cat - >/tmp/logfile然后,在window2中:
(ls -l /tmp/foo /tmp/nofile /tmp/foo1 /tmp/nofile /tmp/nofile; echo successful test; ls /tmp/nofile1111) 2>&1 1>/tmp/fifo | tee /tmp/fifo 1>/dev/pts/2在这里,您用任何要显示stderr的tty替换/dev/pts/2。
子subshell中的各种成功和不成功命令的原因只是为了生成一个混合的输出流和错误消息流,这样您就可以在日志文件中验证正确的顺序。一旦您了解了它的工作原理,将“ls”和“echo”命令替换为您选择的脚本或命令。
使用该方法,可以保持输出和错误的顺序,语法简单明了,并且只有一个对输出文件的引用。另外,在你想要的任何地方放置额外的stderr副本都是灵活的。
https://stackoverflow.com/questions/2871233
复制相似问题