我用来exec
将脚本的所有输出发送到文件:exec > file.errout 2>&1
。但是,在脚本中间,我想向终端和文件发送几条消息。我找到了这段代码这里,但它需要在每个终端消息的两侧添加两行代码并通过管道传输到tee
:
exec > file.errout 2>&1
...
echo "messages only directed to the file"
...
exec >/dev/tty
echo "message i want directed to the terminal" | tee file.errout
exec > file.errout 2>&1
...
echo "more messages only directed to the file"
...
有没有更简单的方法来做到这一点?
答案1
您不必一定这样做。使用将所有标准输出内容放入文件后exec
,只需将要放入终端的语句分组tee
到/dev/tty
exec > file.errout 2>&1
echo "messages only directed to the file"
{
echo "message i want directed to the terminal and file" ;
echo "more more message i want directed to the terminal and file" ;
} | tee /dev/tty
echo "more messages only directed to the file"
您不需要exec >/dev/tty
每次都这样做,因为凭借您的初始exec
行,所有标准输出都已记录到文件中。
答案2
在 bash 和 zsh 中,你可以尝试这样的操作:
exec >file.errout 2>&1
# ...
exec {foo}>&1 > >(tee /dev/tty) 2>&1 # temporarily redirect
echo bla
ls no_such_file
exec >&$foo 2>&1 # restore
# ...
重定向exec {var}>&1 ... exec >&$var
/恢复与 类似exec 7>&1 .. exec >&7
,只是 bash 本身会获取一个未使用的文件描述符并将其存储在变量中$var
,而不是必须使用某个固定的数字,这可能与其余代码冲突。这种形式的重定向是 ksh 扩展,bash 和 zsh 也支持。
重定向exec > >(...)
+进程替换组合虽然实用,但存在一些怪癖和错误(并且可能在 ksh93 中不起作用)。
当然,您可以将命令分组在一个{...}
块中,并将整个块的输出重定向到管道| tee /dev/tty
。这是最简单、最便携的。
它的问题是任何变量分配都将发生在子 shell 中,而不是在主脚本中:
a=before
{
a=$(pwd)
# ...
} | tee /dev/tty
echo "$a" # still "before"