我试图通过使用ctrl+来阻止用户取消脚本c。以下脚本完全执行,只是rsync
坚持要死,并显示错误Killed by signal 2
。
是否可以避免rsync
死亡?如果可以,我可以将其放在后台吗,还是应该放在前台?
脚本:
trap '' SIGINT SIGTERM SIGQUIT
cd /tmp
nohup rsync -e 'ssh -o LogLevel=ERROR' -av --timeout=10 --delete-excluded myapp.war myserver:/tmp/ < /dev/null > /tmp/teste 2> /tmp/teste2
let index=0
while [ $index -lt 400000 ]
do
let index=index+1
done
echo "script finished"
echo "index:$index"
我怀疑 ssh 通道在 之前就死掉了。在 pid 中的命令rsync
输出结束后:strace
rsync
[...]
write(4, "\374\17\0\7", 4) = 4
select(5, NULL, [4], [4], {10, 0}) = 1 (out [4], left {9, 999998})
--- SIGINT (Interrupt) @ 0 (0) ---
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 255}], WNOHANG, NULL) = 12738
wait4(-1, 0x7fffaea6a85c, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn(0xffffffffffffffff) = 0
select(0, NULL, NULL, NULL, {0, 400000}) = 0 (Timeout)
rt_sigaction(SIGUSR1, {SIG_IGN, [], SA_RESTORER, 0x3fcb6326b0}, NULL, 8) = 0
rt_sigaction(SIGUSR2, {SIG_IGN, [], SA_RESTORER, 0x3fcb6326b0}, NULL, 8) = 0
wait4(12738, 0x7fffaea6aa7c, WNOHANG, NULL) = -1 ECHILD (No child processes)
getpid() = 12737
kill(12738, SIGUSR1) = -1 ESRCH (No such process)
write(2, "rsync error: unexplained error ("..., 72) = 72
write(2, "\n", 1) = 1
exit_group(255) = ?
Process 12737 detached
答案1
从实验中可以清楚地看出,其rsync
行为与其他工具类似,ping
并且不会从调用 Bash 父级继承信号。
因此,您必须发挥一点创造力,做如下的事情:
$ cat rsync.bash
#!/bin/sh
set -m
trap '' SIGINT SIGTERM EXIT
rsync -avz LargeTestFile.500M [email protected]:/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
怎么运行的
这里的技巧是,我们通过告诉 Bashset -m
禁用其中任何后台作业的作业控制。然后,我们将运行后台作业rsync
,然后运行一个wait
命令,该命令将等待最后一个运行命令,rsync
直到它完成。
然后我们用 来保护整个脚本trap '' SIGINT SIGTERM EXIT
。
参考
答案2
您需要在脚本执行期间捕获Ctrl+ 。C
#!/bin/bash
trap ctrl_c INT
function ctrl_c() {
echo "Oops CTRL-C not allowed!"
}
for i in `seq 1 5`;
do
echo "doing something... blah blah blah... try pressing Ctrl+C"
sleep 1
done