bash脚本使用像tee这样的文件描述符复制i / o

时间:2014-09-07 03:15:53

标签: bash logging io file-descriptor tee

-------- EDIT

我想将文件描述符同时路由到MULTIPLE位置。例如,我希望我的脚本中的每个命令都能同时将stdout打印到/ dev / ps / 9和./myscript.stdout。我知道我可以在每一行之后使用tee来有效地做到这一点,但有没有办法用文件描述符做呢?

如果您发现下面的伪代码混淆了问题,请忽略它并专注于前一段。我昨晚刚刚写下了这些东西,今天早上我甚至发现它令人困惑。

--------

exec 3>(tee /dev/ps/9 ./myscript.stdout)
exec 4>&1
exec 1>&3

这里的一些代码......同时将stdout输出到终端和日志文件

exec 1>&4
exec 4>&-
exec 3>&-

更多代码......正常运作

这里的关键是我不想在每一行代码之后使用tee

如果我的伪代码使问题比它需要的更令人困惑,我提前道歉。如果有疑问,请阅读我最近编辑的第一段,忽略其余部分。

3 个答案:

答案 0 :(得分:4)

  

我希望我的脚本中的每个命令都能将stdout打印到/ dev / ps / 9   和./myscript.stdout在同一时间。

exec 1> >(tee ./myscript.stdout >/dev/ps/9)

以上结合了重定向和流程替换。单独使用重定向,可以将stdout发送到文件。例如:

exec 1> filename

但是,使用bash,文件名通常可以替换为命令。这称为进程替换,它看起来像>(some command)<(some command),具体取决于是否要写入或读取进程。在我们的例子中,我们想要写一个tee命令。因此:

exec 1> >(some command)

或者,更具体地说:

exec 1> >(tee ./myscript.stdout >/dev/ps/9)

请注意,我们必须维护重定向(1>)和进程替换(>(tee ./myscript.stdout >/dev/ps/9)之间的空间。如果没有空格,看起来我们试图附加到名称的文件以parens开头,这会产生bash错误。

有关详细信息,请参阅man bash中标题为“重定义”和“过程替换”的部分。

答案 1 :(得分:0)

#!/bin/bash

random=$$ # generate a random seed number to name the log files with
out=out.$random
err=err.$random
dev=`echo $(who -m) | cut -d' ' -f2` # for finding the right pseudo-terminal
: >$out # create the log files or empty their contents
: >$err # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

exec 1> >(tee ./$out >/dev/$dev) # I don't know how this works but it does
exec 2> >(tee ./$err >/dev/$dev) # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
echo # writing directly to the pts in /dev doesn't look right until sending a blank line

##########################################

echo 'hello'

for i in `seq 0 1 10`; do
    echo $i
done

bad_command

感谢@ John1024

这是一个希望对此进行测试的其他人的脚本。

有人可以向我详细解释执行行。

例如,为什么在箭头后面有一个空格:

exec 1> 

答案 2 :(得分:-1)

#!/bin/bash
logfile=$$.log
exec > $logfile 2>&1 | tee
echo "test"

$$执行随机种子编号,这是可选的。