我在整个SO中仔细研究了20个问题,以寻找一个没有运气的解决方案。这似乎是一项常见的任务。
我对bash脚本有以下要求:
stdout
发送到log.out
,而不要进行控制台stderr
发送到log.out
并进行控制台log.out
?)目前,我正在尝试以下方法来实现这一目标:
#!/bin/bash
> log.out
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>>log.out 2>&1
# Test
echo "status goes to console" >&3
echo "stderr goes to file + console" >&2
echo "stdout goes to file"
我对这段代码的理解大概是...
这很好,除了不会向控制台显示错误之外。
所以,我想,我将在单独的bg流程中将/dev/stderr
引向&3
,并将此行添加到第二个exec
下:
cat /dev/stderr >&3 &
我不明白为什么,但是,这也会将stdout发送到&3,所以我的控制台显示为:
echoes goes to console
stderr goes to file + console
stdout goes to file
我尝试了50种组合,但均未成功。经过大量阅读之后,我倾向于使用(自定义?)C程序或类似程序来实现这一目标,这对我来说似乎有点疯狂。
非常感谢您的帮助。
嘿,感谢@ charles-duffy的评论和回答,我能够对我现有的脚本进行非常小的修改,从而实现了我所寻找的大致概念:
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>log.out 2> >(tee /dev/tty >&1)
缺点是消息确实在日志文件中乱序显示。
答案 0 :(得分:1)
假设您具有bash 4.1或更高版本:
# make copies of orig stdout, /dev/tty, and our log file FDs
exec {orig_stdout_fd}>&1
exec {tty_fd}>/dev/tty
exec {file_fd}>log.out
# ...and set them up however you wish, using ''tee'' for anything that goes two places
exec >&$file_fd # redirect stdout only to the log file
exec 2> >(tee /dev/fd/"$tty_fd" >&$file_fd) # redirect stderr to both sinks
请注意,对stderr的写入将比对stdout的写入花费更长的时间(因为它们正在通过FIFO),因此可能会丢失顺序。