Bash没有在rsync/subshel​​l exec语句中捕获中断

Zac*_*c B 10 linux bash shell rsync bash-trap

语境:

我有一个bash脚本,其中包含一个子shell和一个EXIT伪信号的陷阱,并且它没有正确捕获中断期间的中断rsync.这是一个例子:

#!/bin/bash
logfile=/path/to/file;
directory1=/path/to/dir
directory2=/path/to/dir

cleanup () {
     echo "Cleaning up!"
     #do stuff
     trap - EXIT 
}

trap '{
    (cleanup;) | 2>&1 tee -a $logfile
}' EXIT

(
    #main script logic, including the following lines:
    (exec sleep 10;);        
    (exec rsync --progress -av --delete $directory1 /var/tmp/$directory2;);

)  | 2>&1 tee -a $logfile
trap - EXIT #just in case cleanup isn't called for some reason
Run Code Online (Sandbox Code Playgroud)

脚本的想法是这样的:大多数重要的逻辑运行在子shell中,通过管道传输tee到日志文件,因此我不必tee将主逻辑的每一行都记录下来.每当子shell结束,或脚本因任何原因停止(EXIT伪信号应捕获所有这些情况),陷阱将拦截它并运行该cleanup()函数,然后删除陷阱.该rsyncsleep命令(睡眠只是一个例子)通过运行exec,以防止僵尸进程的创建,如果我杀了父脚本,而他们正在运行,并且每个潜在的,长期运行的命令被包裹在自己的子shell,这样,当exec完成后,它不会终止整个脚本.

问题:

如果我kill在exec/subshel​​l wrapped sleep命令期间中断脚本(通过或CTRL + C),陷阱正常工作,我看到"正在清理!" 回应并记录.如果我在rsync命令期间中断脚本,我会看到rsync结束,然后写入rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(544) [sender=3.0.6]屏幕,然后脚本就会死掉; 没有清理,没有陷阱.为什么没有中断/杀死rsync触发陷阱?

我尝试过使用--no-detach带有rsync 的开关,但它没有改变任何东西.我有bash 4.1.2,rsync 3.0.6,centOS 6.2.

nhe*_*hed 3

如何将 X 点的所有输出重定向到 tee,而不必在各处重复它并弄乱所有子 shell 和执行器......(希望我没有错过任何东西)

#!/bin/bash
logfile=/path/to/file;
directory1=/path/to/dir
directory2=/path/to/dir

exec > >(exec tee -a $logfile) 2>&1

cleanup () {
     echo "Cleaning up!"
     #do stuff
     trap - EXIT 
}
trap cleanup EXIT

sleep 10
rsync --progress -av --delete $directory1 /var/tmp/$directory2
Run Code Online (Sandbox Code Playgroud)