在bash脚本中,我想:
loglowlevel.txt
),我写了一个基本脚本,将stdout
和sterr
重定向到FD 3. loglowlevel.txt
已正确填充。但我仍然坚持指定高级日志的选项。
#!/bin/bash -
# create fd 3
exec 3<> loglowlevel.txt
# redirect stdout and stderr to fd 3
exec 1>&3
exec 2>&3
# high-level logs' redirection below is wrong
echo "high-level comment" 3>&1
# low-level logs should remain redirection-free, as below
echo "low-level comment"
ls notafile
# close fd 3
3>&-
这是它的作用:
$ redirect.sh
$ cat loglowlevel.txt
low-level comment
ls: cannot access notafile: No such file or directory
我也期望在终端上打印high-level comment
。
第二个脚本,不同的策略:
#!/bin/bash -
function echolowlevel() {
echo $1 &>loglowlevel.txt
}
function echohighlevel() {
echo $1 |& tee loglowlevel.txt
}
echohighlevel "high-level comment 1"
echolowlevel "low-level comment 1"
echohighlevel "high-level comment 2"
ls notafile
这是它的作用:
$ redirect.sh
high-level comment 1
high-level comment 2
ls: cannot access notafile: No such file or directory
$ cat loglowlevel.txt
high-level comment 2
这里有两个问题:
ls
的loglowlevel.txt
中需要它。high-level comment 1
已在loglowlevel.txt
。我更喜欢 Take 1 背后的想法。但是如何在保留两个high-level comment
命令的同时将exec
输出到stdout?
答案 0 :(得分:3)
#!/bin/sh
FIFO=/tmp/fifo.$$ # or use tmpfile, or some other mechanism to get unique name
trap 'rm -f $FIFO' 0
mkfifo $FIFO
tee -a loglowlevel.txt < $FIFO &
exec >> loglowlevel.txt
exec 3> $FIFO
echo high-level >&3 # Appears on original stdout and in loglowlevel.txt
echo low-level # Appears only in loglowlevel.txt
答案 1 :(得分:1)
William Pursell答案的简短版本,用于支持进程替换的shell和操作系统:
exec 3>> >(tee -a loglowlevel.txt)
exec >> loglowlevel.txt
echo high-level >&3 # Appears on original stdout and in loglowlevel.txt
echo low-level # Appears only in loglowlevel.txt
在此示例中,写入文件描述符3有效地写入后台tee
进程的标准输入,该进程附加到文件“loglowlevel.txt”。
对此功能的支持各不相同。它不是POSIX标准的一部分,但它至少由bash
,ksh
和zsh
提供。每个shell都需要一些操作系统支持。例如,bash
版本需要命名管道的可用性(在威廉的解决方案中由mkfifo
创建的对象)或通过/dev/fd
访问打开的文件。