Bash script that will survive disconnection, but not user break

荒凉一梦 提交于 2019-12-25 11:57:27

问题


I want to write a bash script that will continue to run if the user is disconnected, but can be aborted if the user presses Ctrl+C.

I can solve the first part of it like this:

#!/bin/bash
cmd='
#commands here, avoiding single quotes...
'
nohup bash -c "$cmd" &
tail -f nohup.out

But pressing Ctrl+C obviously just kills the tail process, not the main body. Can I have both? Maybe using Screen?


回答1:


I want to write a bash script that will continue to run if the user is disconnected, but can be aborted if the user presses Ctrl+C.

I think this is exactly the answer on the question you formulated, this one without screen:

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

Note however that nohup is not reliable. When the invoking user logs out, chances are that nohup also quits immediately. In that case disown works better.

bash -c "$cmd" &
CHPID=$!
disown



回答2:


This is probably the simplest form using screen:

screen -S SOMENAME script.sh

Then, if you get disconnected, on reconnection simply run:

screen -r SOMENAME

Ctrl+C should continue to work as expected




回答3:


Fact 1: When a terminal (xterm for example) gets closed, the shell is supposed to send a SIGHUP ("hangup") to any processes running in it. This harkens back to the days of analog modems, when a program needed to clean up after itself if mom happened to pick up the phone while you were online. The signal could be trapped, so that a special function could do the cleanup (close files, remove temporary junk, etc). The concept of "losing your connection" still exists even though we use sockets and SSH tunnels instead of analog modems. (Concepts don't change; all that changes is the technology we use to implement them.)

Fact 2: The effect of Ctrl-C depends on your terminal settings. Normally, it will send a SIGINT, but you can check by running stty -a in your shell and looking for "intr".

You can use these facts to your advantage, using bash's trap command. For example try running this in a window, then press Ctrl-C and check the contents of /tmp/trapped. Then run it again, close the window, and again check the contents of /tmp/trapped:

#!/bin/bash

trap "echo 'one' > /tmp/trapped" 1
trap "echo 'two' > /tmp/trapped" 2

echo "Waiting..."
sleep 300000

For information on signals, you should be able to man signal (FreeBSD or OSX) or man 7 signal (Linux).

(For bonus points: See how I numbered my facts? Do you understand why?)

So ... to your question. To "survive" disconnection, you want to specify behaviour that will be run when your script traps SIGHUP.

(Bonus question #2: Now do you understand where nohup gets its name?)



来源:https://stackoverflow.com/questions/19967251/bash-script-that-will-survive-disconnection-but-not-user-break

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!