如何重定向zsh / bash的标准输出并稍后还原

时间:2019-11-25 15:37:46

标签: bash zsh io-redirection

在python中,您可以

sys.stdout = open('log', 'w') # begin redirect

然后输出将改为写入log

您可以使用以下方法恢复正常行为

sys.stdout = sys.__stdout__   # end redirect, restore back

如何在zsh和bash中实现类似的效果?

P.S。,

  • 子外壳中命令的stdout也应重定向。
  • ls > log不是我想要的。

为了澄清,我想要的是

ls   # output to terminal
# begin redirect to `log`
ls   # output to `log`
find -type f   # output to `log`
...  # output to `log`
# end redirect, restore back
ls   # output to terminal

修改 下面不是我想要的

  • 重定向一组命令。
  • tail -f用于监视。

正如该问题的前几行所述, 我想要的是

# ...
cmd1    # normal behavior
# begin redirection
cmd2   # redirect to file
# some times later
cmd2   # redirect to file
# ...
cmdN   # redirect to file
# end redirection
cmdN+1 # normal behavior
# ...

3 个答案:

答案 0 :(得分:3)

通常,您将重定向命令组的输出,而不是重定向和还原Shell本身的输出。

ls                    # to terminal
{
  ls
  find -type f
} > log               # to log
ls                    # to terminal again

整个{ ... }分隔的命令组的标准输出将重定向到文件。该组中的命令从该组继承其标准输出,而不是直接从Shell继承。

这类似于在Python中执行以下操作:

from contextlib import redirect_stdout

print("listing files to terminal")
with open("log", "w") as f, redirect_stdout(f):
    print("listing files to log")
    print("finding files")
print("listing files to terminal")

在shell中,可以通过使用execdemonstrated by oguz ismail来完成标准输出的强制重定向,尽管命令组可以使重定向的开始和结束位置更加清楚。 (这也避免了需要查找未使用的文件描述符并记住更多的奥秘shell语法。)

答案 1 :(得分:2)

您可以使用tee命令登录到文件以及打印到控制台:

ls                         # output to terminal
# begin redirect to `log`
ls  | tee -a log           # output to `log`
find -type f | tee -a log  # output to `log`
...  # output to `log`
# end redirect, restore back
ls   # output to terminal

答案 2 :(得分:1)

使用exec进行永久重定向。例如:

ls              # to tty 
exec 3>&1 >log  # redirect to log, save tty
ls              # to log
find -type f    # ditto
exec >&3        # restore tty
ls              # to tty