我正在读取一个文件并将整个输出重定向到一个文件。我想将某些表达式的 stdout 和 stderr 重定向到屏幕,如下所示(仅是一个示例):
#!/bin/bash
OLDIFS=$IFS
while IFS='|'
while read fname fpath dname dpath ; do
echo "$fname" >> redirect to screen
echo "$fpath"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" >> redirect to screen
done > logfile
我尝试过>$(tty)
,但没有成功。这也不起作用:
while read fname fpath dname dpath; do
echo "$fname" >&1
echo "$fpath"
echo "$dname"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" >&1
done > logfile
我无法使用,tee
因为它重定向了全部的输出到屏幕。我怎样才能实现这个目标?
答案1
while …; do echo "$fname" >&1 done > logfile
命令的标准输出echo
被重定向到其标准输出。换句话说,>&1
是一个空操作。 in1
指定>&1
使用它的命令的文件描述符 1,而不是某些神秘选择的外部范围。
要重定向到外部作用域中可用的文件,请在该外部作用域中复制文件描述符,并且不要重定向重复的文件描述符。
while read fname fpath dname dpath; do
echo "$fname" >&3
echo "$fpath"
echo "$dname"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" >&3
done 3>&1 >logfile
请注意循环中重定向的顺序:首先创建一个文件描述符 3,该文件描述符 3 位于文件描述符 1(标准输出)当前所在的位置,然后将文件描述符 1 重定向到其他位置。
或者,您可以打开不同描述符上的日志文件。
while read fname fpath dname dpath; do
echo "$fname"
echo "$fpath" >&3
echo "$dname" >&3
echo "$dpath" >&3
diff "$fpath/$fname" "$dpath/$dname"
done 3>logfile
答案2
您的while
循环是非交互式的,因此没有 tty。在进入循环之前你必须保存你的 tty 设备。所以你会得到类似的东西:
my_tty=$(tty)
while read fname fpath dname dpath ; do
echo "$fname" | tee ${my_tty}
echo "$fpath"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" | tee ${my_tty}
done > logfile