将输出重定向到终端

redirect output to terminal

我正在尝试了解重定向输出。

我有代码:

#!/bin/bash
function function1 () {
    log=.log

    exec 3>&1
    exec 1>>$log
    exec 2>&1

    echo checking $log >&3
    echo txt to $log
}

function1 log1
function1 log2

exit 0

我得到的输出是:

checking log1.log

和文件 log1.log 内容

txt to log1.log
checking log2.log

和文件 log2.log 内容

txt to log2.log

我真正想要的是内容为

的文件log1.log
txt to log1.log

和文件 log2.log 内容

txt to log2.log

并输出到终端。

checking log1.log
checking log2.log

请问我该怎么做? 我知道我可以使用 function1 log1 > log1.log 2>&1,但是我不能在 function1 中将 echo 重定向回终端,我可以,但结果相似。

应该这样做

#!/bin/bash
function function1 () {
    log=.log

    echo checking $log
    echo txt to $log >$log
}

function1 log1
function1 log2

exit 0

当您只使用一次更改后的目标时,没有理由存储对任何特定文件描述符的更改。

如果您确实想使用这种方法,比如说因为您要重定向很多命令,您至少有 2 个选择:

  • 运行 子 shell 中的重定向和关联命令,因此当它退出时,您仍在处理原始流
  • 将重定向视为要在函数调用中保存的寄存器 - 将它们推送到临时文件(如上面的 &3 中),然后在调用后恢复它们。

不知道你为什么要这样做,除非你不公开所有信息,否则另一个答案是更好的方法,但问题在于你对文件描述符如何工作的理解。

第一次

exec 3>&1     ## Assign 3 to where 1 is currently pointing which is /dev/tty
exec 1>>$log  ## assigns 1 to point to logfile
exec 2>&1     ## Assigns stderr to the 1 which currently points at the logfile

第二次

exec 3>&1     ## Assign 3 to where 1 is currently pointing which is the old logfile
exec 1>>$log  ## assigns 1 to point to new logfile
exec 2>&1     ## Assigns stderr to the 1 which currently points at the new logfile

如您所见,文件描述符会记住它们指向的位置,并简单地指向您告诉它们的任何位置。

如果你想这样做,而不是重定向到 1,直接重定向到 /dev/tty,因为与 1 不同,这永远不会改变(希望如此!)。

#!/bin/bash
function function1 () {
    log=.log

    exec 3>/dev/tty
    exec 1>>$log
    exec 2>&1


    echo checking $log >&3
    echo txt to $log

    exec 1>/dev/tty # Probably want this line as well so your not writing to 
                    #  the logfile for the rest of the script
} 

function1 log1
function1 log2

exit 0

如果你想设置 stdout 和 stderr 然后在函数中恢复它们:

function function1 () {
    log=.log
    exec 4>&2 3>&1 1>>$log 2>&1 # save 1 and 2 to 3 and 4
    echo checking $log >&3
    echo txt to $log
    exec 1>&3 2>&4 3>&- 4>&- # restore 1 and 2
}

3>&-关闭3,只是为了完整。