将标准输出和标准输入重定向到文件

Redirect stdout and stdin to file

我可以写入和读取文件:

echo a > b.txt
read c < b.txt

Bash 是否可以隐式执行此操作?类似于:

<turn on implicit mode>
echo a
read c
<turn off implicit mode>

当“隐式模式”打开时,所有 stdout 转到 b.txt 和所有 stdin 阅读 来自 b.txt。我试过了:

exec > b.txt

但它只影响 stdout.

没有办法让 bash 假设这种行为,特别是考虑到 b.txt 是一个命令的输入和另一个命令的输出。类似问题有多种解决方案,根据您的实际问题可能适用:

  1. 假设您的意思是在脚本中而不是在交互模式中,您可以使用大括号重定向一组命令,这样您就不必拼写所有内容。如果您试图在命令组中同时设置 b.txt 源和目标,它将无法工作。

    {
      echo a
      read c
    } <b_in.txt >b_out.txt
    
  2. 如果 b.txt 存在这一事实并不重要,您可以只使用管道,或带有 tee:

    的管道
    echo a | read c
    echo a | tee b.txt | read c
    
  3. 如果你需要b.txt因为它表现为一个文件,你也可以考虑进程替换。

    command_that_takes_a_file <(echo a)
    command_that_takes_stdin < <(echo a)
    

您可以使用 exec 同时重定向 stdin 和 stdout

exec > b.txt < b.txt
echo a
read c

我不确定这是否会读取它所写的内容,但我测试了它并且它有效。

您可以通过在其他 FD 中复制原始 FD 来恢复它,然后在完成后恢复它们。

exec 10<&0 11>&1 > b.txt < b.txt
echo a
read c
exec <&10 10<&- >&11 11>&-
echo $c

根据这里的回复,我想出了这个:

d=`tty`
exec >b.txt <b.txt
echo a
read c
exec >$d <$d

我还意识到单独保留 stdout 和 stdin 可能更好:

exec 3>b.txt 4<b.txt
echo a >&3
read c <&4

在我的例子中,我有一个通过 stdin/stdout 通信的 client/server,我想捕获这些流。这是 bash 脚本:

cat - | tee stdin.log | $cmd | tee stdout.log