我有一个大的bash脚本,我想全局将所有stdout / stderr重定向到一个文件,除了一些进度指示器,如特定的回显消息。例如,请考虑以下脚本
#!/bin/bash
# all stdout and stderr go to out.log
exec &> out.log
special_echo "starting"
# many other commands go here
# which output both the stdout and stderr
# also some special_echo commands in here,
# for example
echo "msg1"
special_echo "middle"
echo "msg2" >&2
special_echo "finished"
运行时输出应为
$ ./script
starting
middle
finished
$
但是,out.log
应该包含
msg1
msg2
如何实施special_echo
功能?我已经尝试过使用文件描述符并回显,但无法将其显示在屏幕上。
有没有办法实现这一目标,而无需将重定向添加到每一行或执行此类answer之类的操作?
答案 0 :(得分:7)
是的,使用另一个文件描述符是可行的方法:
#!/bin/bash
exec 3>&1
special_echo () {
echo "$@" >&3
}
exec &> out.log
special_echo "starting"
echo "msg1"
special_echo "middle"
echo "msg2" >&2
special_echo "finished"
答案 1 :(得分:1)
重定向到/ dev / tty,这是控制终端。也适用于输入。
答案 2 :(得分:0)
在脚本开始时,将stdout
和stderr
保存为自定义描述符。
# all stdout and stderr go to out.log
exec 3>&1 4>&2 &>out.log
您可以使用3>/dev/stdout
代替3>&1
等,或将其拆分为多个exec
重定向行,如果您更容易理解。 >
然后您只需使用它们
echo "starting" >&3
echo "msg1"
echo "middle" >&3
echo "msg2" >&2
echo "finished" >&3
您不能使用>/dev/stdout
,因为它实际上已被exec
覆盖,因此必须使用自定义描述符。
关于此问题最好的部分是您仍然可以访问原始的stderr
,而您不会使用/dev/tty
echo "special error" >&4
如果需要的话,您可以完全撤消脚本其余部分的重定向。
#restore original
exec >&3 2>&4
echo "this is special now"
没有功能,没有变量,就可以了。