如何完全记录所有 bash 脚本操作?

Blu*_*ark 77 scripting linux ssh bash log-files

从我的脚本输出中,我想捕获所有带有错误消息的日志数据,并将它们全部重定向到日志文件。

我有如下脚本:

#!/bin/bash
(
echo " `date` : part 1 - start "
ssh -f admin@server.com 'bash /www/htdocs/server.com/scripts/part1.sh logout exit'
echo " `date` : sleep 120"
sleep 120
echo " `date` : part 2 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part2.sh logout exit'
echo " `date` : part 3 - start"
ssh admin@server.com 'bash /www/htdocs/server.com/scripts/part3.sh logout exit'
echo " `date` : END"
) | tee -a /home/scripts/cron/logs
Run Code Online (Sandbox Code Playgroud)

我想查看文件中的所有操作 /home/scripts/cron/logs

但是我只看到了我在echo命令后放置的内容。

如何检查SSH命令成功的日志?

我需要收集所有日志。我需要它来监视脚本中每个命令的结果,以便更好地分析脚本失败时发生的情况。

nic*_*bot 114

我通常在每个脚本的开头放置类似于以下内容的内容(尤其是当它作为守护程序运行时):

#!/bin/bash
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2>&1
# Everything below will go to the file 'log.out':
Run Code Online (Sandbox Code Playgroud)

解释:

  1. exec 3>&1 4>&2

    保存文件描述符,以便它们可以恢复到重定向之前的任何内容,或者使用它们自己输出到以下重定向之前的任何内容。

  2. trap 'exec 2>&4 1>&3' 0 1 2 3

    恢复特定信号的文件描述符。通常不需要,因为它们应该在子 shell 退出时恢复。

  3. exec 1>log.out 2>&1

    重定向stdout到文件,log.out然后重定向stderrstdout. 请注意,当您希望它们转到同一个文件时,顺序很重要。stdout 必须将之前重定向stderr被重定向到stdout

从那时起,要在控制台上查看输出(也许),您只需重定向到&3. 例如,

echo "$(date) : part 1 - start" >&3
Run Code Online (Sandbox Code Playgroud)

stdout在执行上面的第 3 行之前,将转到任何被指示的地方,大概是控制台。

  • @radztech 追加是 `>>`,所以 `exec 1>>log.out 2>&1`。 (4认同)
  • 功夫不负有心人!!!- 更好的是使用`trap 'exec 2>&4 1>&3' 0 1 2 3 RETURN`。RETURN 伪 sigspec 每次使用 . 或源内置函数完成执行。为此(以及其他原因),我在我的脚本中添加了最后两行:`return` 和 `exit 0` - 只需我的 2 美分,向你致敬 @nicerobot ! (3认同)
  • @PiyushChordia 链接修复:http://www.cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html (2认同)

Ale*_*lst 26

当我阅读您的问题时,您不想记录输出,而是记录整个命令序列,在这种情况下,其他答案将无济于事。

使用 -x 调用 shell 脚本以输出所有内容:

sh -x foo.sh

登录到您想要的文件:

sh -x foo.sh >> /home/scripts/cron/logs

  • +1 表示 -x 选项 (4认同)
  • @JesseAdelman,因为 xtrace 将所有内容输出到 sterr,所以您需要重定向 stderr 以及 stdout,这就是 `&>` 的作用。 (2认同)

Chr*_*ian 23

要将 ssh 输出到您的日志文件,您必须重定向stderrstdout. 您可以通过2>&1在 bash 脚本之后附加来完成此操作。

它应该是这样的:

#!/bin/bash
(
...
) 2>&1 | tee ...
Run Code Online (Sandbox Code Playgroud)

当这没有以正确的顺序显示消息时,尝试添加另一个子shell:

#!/bin/bash
((
...
) 2>&1) | tee ...
Run Code Online (Sandbox Code Playgroud)

  • 这很好用。实际上,您可以使用以下命令同时指示 stdout 和 stderr:`( ... ) |& tee output.log` (3认同)

Ama*_*rus 11

在 bash 中,您可以 putset -x并且它会在此之后打印出它执行的每个命令(以及 bash 变量)。你可以用 关闭它set +x

如果你想成为偏执狂,你可以把set -o errexit你的脚本。这意味着如果一个命令返回非零退出代码,脚本将失败并停止,这是 Unix 标准方式来表示出现问题。

如果你想获得更好的日志,你应该看看tsmoreutils是Debian / Ubuntu的软件包。它将在每一行前面加上一个时间戳并将其打印出来。所以你可以看到事情发生的时间。

  • “set -o errexit”必须与“set -e”相同 (2认同)