将我的bash的输出重定向到日志文件

安德里亚·莫罗(Andrea Moro)

我现在正在执行一系列的bash脚本,我想捕获在输出文件中运行的命令的值。

我以为可以通过将我的命令与合并来实现,| tee -a outputfile.txt但这仅针对脚本1捕获。

脚本2..4等未将输出附加到文件中。

环顾四周,输出也可以通过这种方式重定向1>&1--但我有些困惑,因为有时我看到数字1被2代替。我想这与消息传递的类型有关。但是,由于我不知道如何调用此输出重定向,因此我一直在寻找信息。

有什么帮助吗?谢谢安德里亚

乔纳森·莱夫勒

基本技巧

有多种实现方法:

exec >outputfile.txt
command1
command2
command3
command4

这会将整个脚本的标准输出更改为日志文件。

我通常更喜欢的方法是:

{
command1
command2
command3
command4
} > outputfile.txt

这会对括号范围内的所有命令进行I / O重定向。小心,你必须同时治疗{},如果他们的命令; 它们不能出现在任何地方。这不会创建子外壳,这是我赞成它的主要原因。

您可以将括号替换为括号:

(
command1
command2
command3
command4
) > outputfile.txt

与括号相比,您可以更轻松地理解括号的位置,因此:

(command1
 command2
 command3
 command4) > outputfile.txt

也可以工作(但是用花括号做到这一点,外壳将无法找到命令{command1(除非您碰巧有一个可执行文件和...周围的文件)。这将创建一个子外壳。括号内的所有变量赋值将不会在括号外显示/访问。有时(但并非总是),这可能是个麻烦。子外壳的增量成本几乎可以忽略不计;它存在,但您可能很难承受测量它。

还有很长的路要走:

command1 >>outputfile.txt
command2 >>outputfile.txt
command3 >>outputfile.txt
command4 >>outputfile.txt

如果您想证明自己是一名新手Shell程序员,请务必使用此技术。如果您希望被视为更高级的Shell程序员,请不要这样做。

请注意,以上所有命令仅将标准输出重定向到命名文件,而将标准错误发送到原始目标位置(通常是终端)。如果要获取标准错误以转到同一文件,只需2>&1在重定向标准输出之后添加(即,将文件描述符2,标准错误发送到与文件描述符1,标准输出相同的位置)。


应用技巧

解决评论中提出的问题。

通过使用2>&1 >> $_logfile(按照下面的回答),我得到了所需的东西,但是现在我确实在输出文件中有了echo...。有没有办法同时在屏幕和文件上打印它们?

啊,所以您不希望所有内容都进入文件...这会使事情变得有些复杂。当然有很多方法。不一定直接。在主重定向之前,我可能会使用exec 3>&1;将文件描述符3设置为与文件描述符1相同的位置(标准输出-或3>&2如果我想要回显标准错误)。然后,我将创建一个函数echoecho() { echo "$*"; echo "$*" >&3; }echoecho Whatever用于执行回显。完成文件描述符3的操作后(如果您不打算退出,则系统将其关闭),您可以使用来关闭它exec 3>&-

当您提到exec那应该是我正在创建的单个脚本文件中执行的命令,并且我将在循环之间执行吗?(只需在下面查看我的答案,看看我如何演变了脚本)。对于其余的建议,我完全失去了你。

没有; 我指的是Bash(shell)内置命令exec它可以用于永久性地进行I / O重定向(针对脚本的其余部分),或者用新程序替换当前脚本,例如exec ls -l—可能是一个不好的例子。

我想现在我比起初时更加困惑:)是否有可能创建一个小例子……以便我能更好地理解它?

评论的缺点是它们难以格式化且大小受限制。这些局限性也是有好处的,但有时必须扩大答案。说的时间到了。

为了便于讨论,我将自己限制为2个命令,而不是问题中的4个命令(但这不会失去任何通用性)。这些命令将是cmd1cmd2,实际上,这是同一脚本的两个不同名称:

#!/bin/bash
for i in {01..10}
do
  echo "$0: stdout $i - $*"
  echo "$0: stderr $i - error message" >&2
done

如您所见,此脚本将消息写入标准输出和标准错误。例如:

$ ./cmd1 trying to work
./cmd1: stdout 1 - trying to work
./cmd1: stderr 1 - error message
./cmd1: stdout 2 - trying to work
./cmd1: stderr 2 - error message
./cmd1: stdout 9 - trying to work
./cmd1: stderr 9 - error message
./cmd1: stdout 10 - trying to work
./cmd1: stderr 10 - error message
$

现在,从Andrea Moro发布答案中,我们发现:

#!/bin/bash

_logfile="output.txt"

# Delete output file if exist
if [ -f $_logfile ];
then
    rm $_logfile
fi

for file in ./shell/*
do
  $file 2>&1 >> $_logfile
done

我不喜欢变量名开头_我不需要看到它。这会将错误重定向到(当前)标准输出要去的地方,然后将标准输出重定向到日志文件。因此,如果子目录shell包含cmd1cmd2,则输出为:

$ bash ex1.sh
./shell/cmd1: stderr 1 - error message
./shell/cmd1: stderr 2 - error message
./shell/cmd1: stderr 9 - error message
./shell/cmd1: stderr 10 - error message
./shell/cmd2: stderr 1 - error message
./shell/cmd2: stderr 2 - error message
./shell/cmd2: stderr 9 - error message
./shell/cmd2: stderr 10 - error message
$

要同时获取文件的标准输出和标准错误,您可以使用以下之一:

2>>$_logfile >>$_logfile
>>$_logfile 2>&1

I / O重定向通常从左到右处理,除了管道控制在|&处理I / O重定向之前将标准输出(如果使用,则为标准错误控制在何处

修改此脚本以生成信息到标准输出以及记录到日志文件,有多种工作方式。我假设shebang线路#!/bin/bash从这里开始。

logfile="output.txt"
rm -f $logfile

for file in ./cmd1 ./cmd2
do
    $file trying to work >> $logfile 2>&1 
done

如果存在该日志文件,则会删除该日志文件(但比以前少了很多)。标准输出和标准错误中的所有内容均保存到日志文件中。我们也可以这样写:

logfile="output.txt"
{
for file in ./cmd1 ./cmd2
do
    $file trying to work
done
} >$logfile 2>&1

或者代码可以使用括号代替大括号,而功能上的细微差别不会实质性地影响此脚本。或者,实际上,在这种情况下,我们可以使用:

logfile="output.txt"
for file in ./cmd1 ./cmd2
do
    $file trying to work
done >$logfile 2>&1

尚不清楚该变量是否必要,但我们将其保留在原位。请注意,这两个都使用“临时” I / O重定向,因为它们仅创建一次日志文件,这反过来意味着无需删除它(尽管可能有这样做的理由,这与事先运行该命令的其他用户有关)并留下一个不可写的文件,但是无论如何您都应该有一个带日期戳的日志文件,这样毕竟不是问题。

显然,如果我们想在原始标准输出以及日志文件中回显某些内容,则我们必须做些不同的事情,因为标准错误和标准输出都将发送到日志文件中。

一种选择是:

logfile="output.txt"
rm -f $logfile

for file in ./cmd1 ./cmd2
do
    echo $file $(date +'%Y-%m-%d %H:%M:%S')
    $file trying to work >> $logfile 2>&1 
done

另一个选择是:

exec 3>&1

logfile="output.txt"
for file in ./cmd1 ./cmd2
do
    echo $file $(date +'%Y-%m-%d %H:%M:%S') >&3
    $file trying to work
done >$logfile 2>&1

exec 3>&-

现在,文件描述符3与原始标准输出位于同一位置。在循环内部,标准输出和标准错误都发送到日志文件,但是echo … >&3将标准输出发送echo到文件描述符3。

如果要将相同的回显输出同时发送到重定向的标准输出和原始的标准输出,则可以使用:

exec 3>&1
echoecho()
{
    echo "$*"
    echo "$*" >&3
}

logfile="output.txt"
for file in ./cmd1 ./cmd2
do
    echoecho $file $(date +'%Y-%m-%d %H:%M:%S')
    $file trying to work
done >$logfile 2>&1

exec 3>&-

输出是:

$ bash ex3.sh
./cmd1 2014-01-07 14:57:13
./cmd2 2014-01-07 14:57:13
$ cat output.txt
./cmd1 2014-01-07 14:57:13
./cmd1: stdout 1 - trying to work
./cmd1: stderr 1 - error message
./cmd1: stdout 2 - trying to work
./cmd1: stderr 2 - error message
./cmd1: stdout 9 - trying to work
./cmd1: stderr 9 - error message
./cmd1: stdout 10 - trying to work
./cmd1: stderr 10 - error message
./cmd2 2014-01-07 14:57:13
./cmd2: stdout 1 - trying to work
./cmd2: stderr 1 - error message
./cmd2: stdout 2 - trying to work
./cmd2: stderr 2 - error message
./cmd2: stdout 9 - trying to work
./cmd2: stderr 9 - error message
./cmd2: stdout 10 - trying to work
./cmd2: stderr 10 - error message
$

这就是我在评论中说的全部内容。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将我的bash的输出重定向到日志文件

来自分类Dev

将我的输出重定向到textarea

来自分类Dev

bash-将输出重定向到日志文件(名称中带有日期)

来自分类Dev

将bash脚本输出重定向到日志文件(不包括菜单)

来自分类Dev

我可以同时将输出重定向到日志文件和后台进程吗?

来自分类Dev

索引将我重定向到其他文件

来自分类Dev

Pitest:如何将日志输出重定向到文件?

来自分类Dev

将整个bash会话重定向到日志文件

来自分类Dev

我可以将日志文件重定向到syslog吗?

来自分类Dev

将我的域名重定向到URL

来自分类Dev

bash标准输出无法重定向到文件

来自分类Dev

Bash将输出重定向到tty和文件

来自分类Dev

Bash将输出重定向到tty和文件

来自分类Dev

Bash脚本:将慢速命令的输出重定向到文件

来自分类Dev

通过bash将输出重定向到文件

来自分类Dev

从我的程序输出重定向到的文件中读取

来自分类Dev

将Shell脚本中的echo输出重定向到日志文件

来自分类Dev

如何将xmlrpc服务器的日志输出重定向到某些文件

来自分类Dev

如何将time命令的输出重定向到日志文件?

来自分类Dev

将未命名管道的输出重定向到c中的日志文件

来自分类Dev

从重定向到日志文件的程序输出中删除进度条

来自分类Dev

如何将xmlrpc服务器的日志输出重定向到某个文件

来自分类Dev

如何将find命令(使用grep)的输出重定向到日志文件?

来自分类Dev

是否可以将nohup输出重定向到nohup.out以外的日志文件?

来自分类Dev

无法将应用程序输出重定向到日志文件

来自分类Dev

将未命名管道的输出重定向到c中的日志文件

来自分类Dev

将带有时间戳的stdout / stderr输出重定向到日志文件

来自分类Dev

如何将输出从cron重定向到日志文件并添加时间戳?

来自分类Dev

将标准输出重定向到文件

Related 相关文章

  1. 1

    将我的bash的输出重定向到日志文件

  2. 2

    将我的输出重定向到textarea

  3. 3

    bash-将输出重定向到日志文件(名称中带有日期)

  4. 4

    将bash脚本输出重定向到日志文件(不包括菜单)

  5. 5

    我可以同时将输出重定向到日志文件和后台进程吗?

  6. 6

    索引将我重定向到其他文件

  7. 7

    Pitest:如何将日志输出重定向到文件?

  8. 8

    将整个bash会话重定向到日志文件

  9. 9

    我可以将日志文件重定向到syslog吗?

  10. 10

    将我的域名重定向到URL

  11. 11

    bash标准输出无法重定向到文件

  12. 12

    Bash将输出重定向到tty和文件

  13. 13

    Bash将输出重定向到tty和文件

  14. 14

    Bash脚本:将慢速命令的输出重定向到文件

  15. 15

    通过bash将输出重定向到文件

  16. 16

    从我的程序输出重定向到的文件中读取

  17. 17

    将Shell脚本中的echo输出重定向到日志文件

  18. 18

    如何将xmlrpc服务器的日志输出重定向到某些文件

  19. 19

    如何将time命令的输出重定向到日志文件?

  20. 20

    将未命名管道的输出重定向到c中的日志文件

  21. 21

    从重定向到日志文件的程序输出中删除进度条

  22. 22

    如何将xmlrpc服务器的日志输出重定向到某个文件

  23. 23

    如何将find命令(使用grep)的输出重定向到日志文件?

  24. 24

    是否可以将nohup输出重定向到nohup.out以外的日志文件?

  25. 25

    无法将应用程序输出重定向到日志文件

  26. 26

    将未命名管道的输出重定向到c中的日志文件

  27. 27

    将带有时间戳的stdout / stderr输出重定向到日志文件

  28. 28

    如何将输出从cron重定向到日志文件并添加时间戳?

  29. 29

    将标准输出重定向到文件

热门标签

归档