对于我正在启动的某些云计算机,我尝试记录到特定文件、系统日志和终端/控制台。
在我的机器设置/云初始化脚本的顶部,我有以下内容:
#!/bin/bash
exec &> >(tee "/tmp/box-setup.log" | logger -t box-setup)
apt-get install -y some-package
这对于将输出发送到文件和系统日志非常有效,但它不会通过管道将输出发送到终端。
一般来说,没有终端输出并不是一个大问题,除非我从远程控制台进行调试。当这种情况发生时,我完全失明了,因为 bash 脚本执行时控制台是空白的。
有没有一种简单的方法使用bash
重定向或其他方式将所有输出(标准输出和标准错误)同时传输到文件、系统日志和终端?
我运行的是 Ubuntu 16.04。
答案1
添加一个嵌套进程替换和另一个,tee
如下所示:
exec &> >(tee >(tee "/tmp/box-setup.log" | logger -t box-setup))
主进程替换中的第一个tee
将 STDOUT/STDERR 发送到终端,也发送到嵌套进程替换,tee
内部将内容保存在文件中/tmp/box-setup.log
,管道也用于将输出发送到logger
STDIN。
答案2
我完全失明了,因为 bash 脚本执行时控制台是空白的。
您可能想以不同的方式解决该问题:在后台运行 bash 脚本,然后运行less /tmp/box-setup.log
并按 F 键以在将行添加到其正在监视的文件中时不断更新屏幕(如tail -f
)。
如果在后台运行脚本出现问题,请使用tmux
或screen
将多个会话复用到一个 ssh 连接上。less
在另一个 shell 中使用相同的命令。
原来的问题:
tee
可以复制到多个目的地。使用特殊文件将其中之一设为终端/dev/tty
。我认为它总是指当前进程的控制tty。或者可能更好/dev/stderr
,因为tee
的 stderr 仍然连接到 shell 的 stderr。 (这可以让您使用 &> /dev/null 使脚本静音)。
exec &> >(tee /dev/stderr "/tmp/box-setup.log" | logger -t box-setup)
顺便说一句,这相当于但比(tee /dev/stderr | tee "/tmp/box-setup.log" | logger ...)
.
可以使用一些文件描述符克隆来提供tee
原始脚本的标准输出,而不是标准错误。
答案3
只需将/dev/stderr
(您的选择)作为输出添加到tee
.
exec &> >(tee /dev/stderr "/tmp/box-setup.log" | logger -t box-setup)
标准输出和标准错误将被合并。如果您想保留它们的顺序,则无法将它们分开,这通常是可取的。无论如何,如果他们都去同一个地方(例如航站楼)也没关系。