gpt4 book ai didi

linux - Bash 在 rsync/subshel​​l exec 语句期间不捕获中断

转载 作者:IT王子 更新时间:2023-10-29 00:07:27 26 4
gpt4 key购买 nike

上下文:

我有一个包含子 shell 和 EXIT 伪信号陷阱的 bash 脚本,它在 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

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

问题:

如果我在 exec/subshel​​l 包装的 sleep 命令期间中断脚本(通过 kill 或 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。

最佳答案

如何将点 X 的所有输出重定向到 tee 而不必在所有地方重复它并弄乱所有子 shell 和 execs ...(希望我没有遗漏任何东西)

#!/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

关于linux - Bash 在 rsync/subshel​​l exec 语句期间不捕获中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9624947/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com