如何在bash中设置两级重定向?
在bash脚本中,我想:如何在bash中设置两级重定向?,bash,io-redirection,Bash,Io Redirection,在bash脚本中,我想: 将每个日志输出到一个文件(loglowlevel.txt)中 但是,在终端(高级)中,仅使它们中的少数可见 比如说,我有20个高级日志和60个低级日志。因此,我想让低级日志“redirection command”保持免费,并且只将重定向内容设置为高级日志 拿1 我编写了一个基本脚本,将stdout和sterr重定向到fd3loglowlevel.txt已正确填充。但我一直在为高级日志指定选项 #!/bin/bash - # create fd 3 exec 3&l
loglowlevel.txt
)中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>&-
我希望高级评论也能打印在终端上
拿2块
第二个脚本,不同的策略:
#!/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
$ cat loglowlevel.txt
low-level comment
ls: cannot access notafile: No such file or directory
$ 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
中使用它
高级注释1
已在loglowlevel.txt
中被吃掉
问题:
我更喜欢采取1背后的想法。但是,在保留两个exec
命令的同时,如何将高级注释
输出到stdout?#/垃圾箱/垃圾箱
#!/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
FIFO=/tmp/FIFO.$$#或使用tmpfile或其他机制获取唯一名称
陷阱'rm-f$FIFO'0
mkfifo$FIFO
tee-a loglowlevel.txt<$FIFO&
exec>>loglowlevel.txt
exec 3>先进先出
echo高级>&3#出现在原始标准输出和loglowlevel.txt中
回声低电平#仅在loglowlevel.txt中出现
#/垃圾箱/垃圾箱
FIFO=/tmp/FIFO.$$#或使用tmpfile或其他机制获取唯一名称
陷阱'rm-f$FIFO'0
mkfifo$FIFO
tee-a loglowlevel.txt<$FIFO&
exec>>loglowlevel.txt
exec 3>先进先出
echo高级>&3#出现在原始标准输出和loglowlevel.txt中
回声低电平#仅在loglowlevel.txt中出现
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将有效地写入附加到文件“loglowlevel.txt”的后台tee
进程的标准输入
对该功能的支持各不相同。它不是POSIX标准的一部分,但至少由bash
、ksh
和zsh
提供。每个shell都需要一些操作系统支持。例如,bash
版本要求提供命名管道(William的解决方案中由mkfifo
创建的对象)或通过/dev/fd
访问打开的文件,这是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将有效地写入附加到文件“loglowlevel.txt”的后台tee
进程的标准输入
对该功能的支持各不相同。它不是POSIX标准的一部分,但至少由bash
、ksh
和zsh
提供。每个shell都需要一些操作系统支持。例如,bash
版本要求提供命名管道(William的解决方案中由mkfifo
创建的对象)或通过/dev/fd
访问打开的文件。输出重定向将输出从一个文件描述符转移到另一个文件描述符,即,它是一对一的映射。您不能让输出单独重定向到两个单独的源。@CarlNorum我不知道tee中的-a
选项。您知道吗?输出重定向将输出从一个文件描述符转移到另一个文件描述符,即,它是一对一映射。您不能让输出单独重定向到两个单独的源。@CarlNorum我不知道tee中的-a
选项。如果进程替换可用,您只需要两行(如果我做对了):exec 3>>(tee-a loglowlevel);exec>>loglowlevel.txt
@William,很好用,谢谢@chepnerexec3>>(tee-a loglowlevel.txt);exec>>loglowlevel.txt
第4行:意外标记“>”附近的语法错误第4行:“exec 3>>>(tee-a loglowlevel)”m-ric:那么,您似乎没有进程替换。你在威廉的剧本中使用了/bin/sh
shebang吗?如果是,请将其更改为#/bin/bash
@chepner你说得对<代码>破折号
投诉。使用#/bin/bash
,您的解决方案有效。你应该把它贴出来作为答案!您能描述一下exec 3>>
是如何工作的吗?我在@m-ric中没有见过这种语法。bash手册页中有关于进程替换的描述。它是一个高度不可移植的结构。如果使用,它将有效地将您的脚本绑定到bash,并使使用任何其他shell变得困难。如果可以使用进程替换,您只需要两行代码(如果我没有弄错的话):exec 3>>(tee-a loglowlevel);exec>>loglowlevel.txt
@William,很好用,谢谢@chepnerexec3>>(tee-a loglowlevel.txt);exec>>loglowlevel.txt
第4行:意外标记“>”附近的语法错误第4行:“exec 3>>>(tee-a loglowlevel)”m-ric:那么,您似乎没有进程替换。你在威廉的剧本中使用了/bin/sh
shebang吗?如果是,请将其更改为#/bin/bash
@chepner你说得对<代码>破折号
投诉。使用#/bin/bash
,您的解决方案有效。你应该把它贴出来作为答案!您能描述一下exec 3>>
是如何工作的吗?我在@m-ric中没有见过这种语法。bash手册页中有关于进程替换的描述。它是一个高度不可移植的结构。如果使用,它将有效地将脚本绑定到bash,并使使用任何其他shell变得困难。