您的位置:首页 > 编程语言 > Python开发

Run python as a daemon process

2016-05-27 01:12 766 查看

I am using `&`: why isn't the process running in the background?

No problem. We won't show you that ad again. Why didn't you like it?

Uninteresting

Misleading

Offensive

Repetitive

Other

Oops! I didn't mean to do this.



up vote9down votefavorite
6

I know that I can append
&
to a command to run the process in the background.

I'm SSH'ing into an Ubuntu 12.04 box and running a python program with
$python program.py &
-- but when I go to close the terminal window I get a message saying that closing the terminal will kill the running process.

Why is this? I am using the ampersand to run the process in the background. How can I get it to run regardless of if I am SSH'ed in?

shell ssh terminal background-process processes
share|improve this question
edited Jun 6 '14 at 23:30



Gilles
342k586121049

asked Jun 6 '14 at 21:30



bernie2436
1,20252435

Duplicate of unix.stackexchange.com/q/4004/69080Joshua Huber Jun 6 '14 at 23:50
apt-get install screen, man screen – captcha Mar 23 at 1:56
add a comment |

5 Answers 5

active oldest votes

up vote25down voteaccepted
When you close a terminal window, the terminal emulator sends a SIGHUP to the process it is running, your shell. Your shell then forwards that SIGHUP to everything it's running. On your local system, this is the ssh. The ssh then forwards the SIGHUP to what it's running, the remote shell. So your remote shell then sends a SIGHUP to all its processes, your backgrounded program.

There are 2 ways around this.

Disassociate the backgrounded program from your shell.
Use the
disown
command after backgrounding your process. This will make the shell forget about it.

Prefix your command with
nohup
(
nohup $python program.py &
). This accomplishes the same thing, but by using an intermediate process. Basically it ignores the SIGHUP signal, and then forks & executes your program which inherits the setting, and then exits. Because it forked, the program being launched is not a child of the shell, and the shell doesn't know about it. And unless it installs a signal handler for SIGHUP, it keeps the ignore action anyway.

Use
logout
instead of closing the terminal window. When you use
logout
, this isn't a SIGHUP, and so the shell won't send a SIGHUP to any of its children.

Additionally you must make sure that your program doesn't write to the terminal through STDOUT or STDERR, as both of those will no longer exist once the terminal exits. If you don't redirect them to something like
/dev/null
, the program will still run, but if it tries to write to them, it'll get a SIGPIPE, and the default action of SIGPIPE is to kill the process).

share|improve this answer
answered Jun 6 '14 at 21:58



Patrick
31k674124

4
Technically,
ssh
dying causes the connection to drop, the connection to drop causes
sshd
on the other end to die. That sshd controlling the master side of the pseudo-terminal that the remote shell runs, when it dies, that's a hang-up (it's like pulling the plug on a real terminal), so the system sends a SIGHUP to the remote shell. – Stéphane Chazelas Jun 6 '14 at 22:04
@StéphaneChazelas That's one thing I've never dug into. If it's the kernel doing it, how does it determine which process to SIGHUP? It obviously doesn't SIGHUP everything with an open file descriptor to that TTY, as programs will remain running as long as they don't try to use it. So does it pick the program that is currently reading from STDIN (since only one can read from STDIN at a time)? – Patrick Jun 6 '14 at 22:14
4
Never mind, answered my own question. POSIX IEEE 1003.1 chap 11, If a modem disconnect is detected by the terminal interface for a controlling terminal ... the SIGHUP signal shall be sent to the controlling process. – Patrick Jun 6 '14 at 22:24
1
Also note that
nohup
generates a
nohup.out
file with output of the program you start with it. May be annoying to delete that file every time you've used nohup to start an app this way (or you'd need to redirect its output to
/dev/null
). – Ruslan Jun 7 '14 at 14:42
add a comment |
No problem. We won't show you that ad again. Why didn't you like it?

Uninteresting

Misleading

Offensive

Repetitive

Other

Oops! I didn't mean to do this.



up vote3down vote
The process is running in the background in the terminal, but the output from
stdout
(and
stderr
) is still being sent to the terminal. To stop this, add
> /dev/null 2>&1
before the
&
to redirect both the outputs to
/dev/null
- adding
disown
also makes sure the process is not killed after you close the terminal:

COMMAND > /dev/null 2>&1 & disown

In your case this would be:

python program.py > /dev/null 2>&1 & disown


share|improve this answer
edited Jun 6 '14 at 21:55

answered Jun 6 '14 at 21:49



Wilf
1,319827

add a comment |
up vote1down vote
When you logout, background processes associated with the login session are normally killed as well. If you want them to be disconnected from the session, run them with
nohup
.

nohup python program.py &


share|improve this answer
edited Jun 6 '14 at 21:47



Patrick
31k674124

answered Jun 6 '14 at 21:37



Barmar
3,791514

add a comment |
up vote0down vote
The
&
operator separates commands to run in parallel, just as
;
separates commands to run in series. Both kinds of commands will still run as a child of the shell process.

So, when you close the shell which started those children, the children will be closed also.

What you appear to want is a daemon process, which is significantly more tricky because it needs to dissociate entirely from the parent process. The shell usually doesn't have a simple way of doing that.

share|improve this answer
answered Jun 7 '14 at 3:28



bignose
1586

add a comment |
up vote0down vote
After the command ending with ampersand (&), at the command prompt run the command "bg"

bash> python program.py & bash> bg This will put the "&" command to the background bash> jobs This will list the jobs running in the background

bash> fg 1 This will bring Job #1 to the foreground

Another way, (to be able to log out)

bash> at now bash> /full/path/python /full/path/program.py bash> ^d
(# That is, Control-D, to run the command, Control-C to cancel)
Multiple lines can be submitted to the "at" command, before the ^d (Control-D) see "man at"

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: