是否可以将 stdout 重定向到 shell 脚本中的非 stderr 流?

Is it possible to redirect stdout to a non-stderr stream inside a shell script?

这与我的 相关但正交。

考虑以下 shell 脚本,我将把它放在一个名为 Play.sh.

的文件中
#!/bin/bash

echo "Send me to standard out"
echo "Send me to standard err" >&2

当我运行这个时,我可以重定向标准输出和标准错误。

$ ./Play.sh  > /dev/null
Send me to standard err
$ ./Play.sh  2> /dev/null
Send me to standard out

所有这些都按预期工作。


我想打开第三个流并强制 echo 输出到第三个流,以便我可以对其进行过滤。类似于以下内容:

#!/bin/bash

echo "Send me to standard out"
echo "Send me to standard err" >&2
echo "Send me to stream 3" >&3

不幸的是,默认情况下第三个流不附加到 /dev/tty

观察到的输出

# This works as desired
./Play.sh  3> /dev/null
Send me to standard out
Send me to standard err

# This does not work as desired.
$ ./Play.sh
Send me to standard out
Send me to standard err
./Play.sh: line 5: 3: Bad file descriptor

期望输出

# This works as desired
./Play.sh  3> /dev/null
Send me to standard out
Send me to standard err

# I would like stream 3 to go to /dev/tty ONLY when not redirected.
$ ./Play.sh
Send me to standard out
Send me to standard err
Send me to stream 3

当且仅当父进程不重定向它时,我可以在 shell 脚本中使用使第三个流指向 /dev/tty 的咒语吗?

实际上,我希望第三个流的行为方式与 stdoutstderr 完全相同:默认为 /dev/tty 并允许父级重定向。

为了完整起见,根据 tripleee 的评论,我真正想要的是以下内容:

#!/bin/bash

echo "Send me to standard out"
echo "Send me to standard err" >&2


if ! (printf '' 1>&3) 2>&-; then
  # File descriptor 3 is not open
  # Option 1: Redirect fd3 to stdout.
  exec 3>&1
  # Option 2: Redirect fd3 to /dev/null.
  # exec 3>/dev/null
fi

# No error here.
echo "Send me to stream 3" >&3

通过此修改,父进程可以在需要时重定向 3,否则将其作为标准输出的一部分。

$ ./Play.sh
Send me to standard out
Send me to standard err
Send me to stream 3

$ ./Play.sh 3> /dev/null
Send me to standard out
Send me to standard err