我想编写一个bash脚本,如果用户断开连接将继续运行,但如果用户按下Ctrl + C,则可以中止。
我可以像这样解决它的第一部分:
#!/bin/bash
cmd='
#commands here, avoiding single quotes...
'
nohup bash -c "$cmd" &
tail -f nohup.out
但是按Ctrl + C显然只会杀死tail
进程,而不是主体。我可以同时拥有吗?也许使用Screen?
答案 0 :(得分:1)
这可能是使用屏幕的最简单形式:
screen -S SOMENAME script.sh
然后,如果断开连接,重新连接时只需运行:
screen -r SOMENAME
Ctrl+C
应继续按预期工作
答案 1 :(得分:1)
事实1 :当终端(例如xterm)关闭时,shell应该向其中运行的任何进程发送SIGHUP(“挂断”)。这可以追溯到模拟调制解调器的日子,当一个程序需要自己清理,如果妈妈碰巧在你上网时拿起电话。信号可能被捕获,因此特殊功能可以进行清理(关闭文件,删除临时垃圾等)。即使我们使用套接字和SSH隧道而不是模拟调制解调器,“丢失连接”的概念仍然存在。 (概念不会改变;所有改变都是我们用来实现它们的技术。)
事实2 : Ctrl - C 的效果取决于您的终端设置。通常情况下,它会发送一个SIGINT,但您可以在shell中运行stty -a
并查找“ intr ”进行检查。
您可以使用bash的trap
命令来利用这些事实。例如,尝试在窗口中运行它,然后按Ctrl-C并检查/tmp/trapped
的内容。然后再次运行它,关闭窗口,再次检查/tmp/trapped
:
#!/bin/bash
trap "echo 'one' > /tmp/trapped" 1
trap "echo 'two' > /tmp/trapped" 2
echo "Waiting..."
sleep 300000
有关信号的信息,您应该能够man signal
(FreeBSD或OSX)或man 7 signal
(Linux)。
(奖励积分:看看我如何编号我的事实?你明白为什么吗?)
所以......对你的问题。要“生存”断开连接,您需要指定在脚本捕获SIGHUP时将运行的行为。
(奖金问题#2:现在您了解nohup
取名的位置吗?)
答案 2 :(得分:1)
我想编写一个bash脚本,如果用户断开连接将继续运行,但如果用户按下Ctrl + C,则可以中止。
我认为这正是你提出的问题的答案,这个没有屏幕:
#!/bin/bash
cmd=`cat <<EOF
# commands here
EOF
`
nohup bash -c "$cmd" &
# store the process id of the nohup process in a variable
CHPID=$!
# whenever ctrl-c is pressed, kill the nohup process before exiting
trap "kill -9 $CHPID" INT
tail -f nohup.out
但请注意,nohup不可靠。当调用用户注销时,很可能nohup也会立即退出。在这种情况下, disown 效果更好。
bash -c "$cmd" &
CHPID=$!
disown