重定向特定行的 stdout 和 stderr

重定向特定行的 stdout 和 stderr

我正在读取一个文件并将整个输出重定向到一个文件。我想将某些表达式的 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

相关内容