bash trap赢得';t忽略信号 请考虑这个BASH脚本: #!/bin/bash trap '' INT echo sleep: sleep 5 echo rsync: rsync -a /usr/lib /var/tmp
按预期,尝试用ctrl-c中断睡眠失败。但是rsync是可中断的(睡眠和rsync的顺序无关紧要)?欢迎任何意见 编辑:bash trap赢得';t忽略信号 请考虑这个BASH脚本: #!/bin/bash trap '' INT echo sleep: sleep 5 echo rsync: rsync -a /usr/lib /var/tmp,bash,signals,rsync,bash-trap,Bash,Signals,Rsync,Bash Trap,按预期,尝试用ctrl-c中断睡眠失败。但是rsync是可中断的(睡眠和rsync的顺序无关紧要)?欢迎任何意见 编辑: 发现了一个不同点:rsync本身启动了两个子进程(客户机/服务器,我认为这会产生两个错误msg),而这些似乎并没有继承其父进程的“无知”。必须深入了解bash源代码并找出陷阱是如何工作的…您是否尝试过使用rsync和--不分离,如SO问题中建议的那样?从实验中可以清楚地看出rsync的行为与其他工具(如ping)类似,并且不会从调用bash继承信号家长 因此,你必须在这方面有
发现了一个不同点:rsync本身启动了两个子进程(客户机/服务器,我认为这会产生两个错误msg),而这些似乎并没有继承其父进程的“无知”。必须深入了解bash源代码并找出陷阱是如何工作的…您是否尝试过使用
rsync
和--不分离,如SO问题中建议的那样?从实验中可以清楚地看出rsync
的行为与其他工具(如ping
)类似,并且不会从调用bash继承信号家长
因此,你必须在这方面有一点创意,并采取如下措施:
$ cat rsync.bash
#!/bin/sh
set -m
trap '' SIGINT SIGTERM EXIT
rsync -avz LargeTestFile.500M root@host.mydom.com:/tmp/. &
wait
echo FIN
现在,当我运行它时:
$ ./rsync.bash
X11 forwarding request failed
building file list ... done
LargeTestFile.500M
^C^C^C^C^C^C^C^C^C^C
sent 509984 bytes received 42 bytes 92732.00 bytes/sec
total size is 524288000 speedup is 1027.96
FIN
我们可以看到文件已完全传输:
$ ll -h | grep Large
-rw-------. 1 501 games 500M Jul 9 21:44 LargeTestFile.500M
工作原理
这里的诀窍是,我们通过set-m
告诉Bash对其中的任何后台作业禁用作业控制。然后我们将rsync
后台接地,然后运行wait
命令,该命令将等待最后一个运行命令rsync
,直到它完成
然后,我们使用trap''SIGINT SIGTERM EXIT
保护整个脚本
工具书类
rsync
正在设置自己的信号处理程序,覆盖您的信号处理程序?下面是指向一个非常类似问题的链接。看看那里可能会有帮助。谢谢你的链接,但是我已经读过了。但是这个问题的解决方案对我没有帮助——或者说我没有正确地理解它:/@tripleee:那么这个陷阱就没用了?为什么ctrl-c会“穿过”外壳?外壳会(或多或少):signal(SIGINT,SIG\u IGN)
。任何子进程(如rsync
)都继承忽略的信号处理。但是,如果rsync
不小心且无条件地发出信号(SIGINT,SIGINT\u handler)
,则会撤消shell保护其免受中断的尝试。这就是为什么书中总是建议您测试:if(signal(SIGINT,SIG_-IGN)!=SIG_-IGN)signal(SIGINT,SIGINT_-handler)代码>。当然,所有这些都是C代码级别的。谢谢Jonathan的详细解释。现在更清楚了。@davak:谢谢你的提示,但是这个选项只适用于作为守护进程运行的rsync。