使用 trap 和 exec 将输出重定向到 bash 中的 tee

使用 trap 和 exec 将输出重定向到 bash 中的 tee

我有一个从文件中读取行并处理每一行的脚本。我希望能够以某种方式进行一些“后处理”,即使脚本没有完成读取所有行,因为我按了 Ctrl+C,它仍然会进行后处理。为了实现这一目标,我正在尝试执行以下两项操作:

  1. 将标准输出重定向到文件;稍后从该文件进行后处理,但是我想看看发生了什么,所以我想重定向到“tee”
  2. 捕获 Ctrl+C 并在那里进行后处理

我设法使 1 或 2 工作,但不能同时工作:

#!/bin/bash

# 2. Either this works 
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
function ctrl_c() {
    echo "** Trapped CTRL-C"
}

# 1. Or this works    
LOGFILE=/tmp/${FILE}.tee
rm ${LOGFILE}
exec > >(tee ${LOGFILE}) 2>&1

function post_process() {
    # use ${LOGFILE}
}

egrep "(${URL_PATH})" ${FILE} |
    while read LINE ; do
        #...
    done

post_process

答案1

您应该忽略后处理函数中的^C/ :SIGINT

preprocess(){
   yes baa
}
postprocess(){
   sed 's/a/z/g'
}
preprocess | { trap '' INT; postprocess; sleep 1; echo DONE; }

当您运行该管道并按 时^Cpreprocess将被终止,但将继续运行,直到消耗掉postprocess产生的所有输出。preprocess

请注意,trap '' INT(使用空字符串作为处理程序)也将SIGINT在子进程中被忽略;不要用例如替换它。trap 'echo INT trapped' INT因为这将导致任何sed等 也被 '^C' 杀死,尽管信号正在父进程中处理。

相关内容