【问题标题】:Redirect stdout and stdin to file将标准输出和标准输入重定向到文件
【发布时间】:2015-10-23 22:48:07
【问题描述】:

我可以读写文件:

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

【问题讨论】:

  • echo a | read c ?!?
  • @Marged 这行不通,因为read 在子shell 中运行,因此它的变量分配不会持续存在。

标签: bash stdout stdin


【解决方案1】:

您可以使用exec 同时重定向标准输入和标准输出

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

【讨论】:

  • 您还可以将当前的tty 保存在一个变量中,并使用它来恢复重定向:mytty=$(tty); ... ; exec &gt; "$mytty" &lt; "$mytty"
  • @j.a.这假设输出最初被定向到 tty。如果脚本在其输出重定向的情况下运行怎么办?
  • 是的@Barmar,它假设。
【解决方案2】:

没有办法让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)
    

【讨论】:

  • 1 没有意义; read 应该从 echo 输出到的同一文件中获取其输入。 2 没有意义,一旦管道完成,c 将不存在
  • 那么进程替换可能就是您正在寻找的,这就是为什么它也在答案中。
【解决方案3】:

就我而言,我有一个通过标准输入/标准输出进行通信的客户端/服务器,我想捕获这些流。这是 bash 脚本:

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

【讨论】:

    【解决方案4】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      相关资源
      最近更新 更多