让其他用户停止/重新启动简单的 bash 守护进程 –使用信号还是什么?
我有一个网络服务器,我在其中运行一些启动缓慢的程序作为守护进程。当我重新编译它们或切换到它们的另一个安装时,有时需要快速重新启动(或停止)。
受到 http://mywiki.wooledge.org/ProcessManagement 的启发,我正在编写一个脚本 名为 daemonise.sh
,看起来像是
#!/bin/sh
while :; do
./myprogram lotsadata.xml
echo "Restarting server..." 1>&2
done
保持“守护进程”运行。因为我有时需要停止它,或者只是 重新启动它,我在屏幕会话中运行该脚本,例如:
$ ./daemonise.sh & DPID=$!
$ screen -d
然后也许我重新编译我的程序,将其安装到新路径,开始 新的出现并想杀死旧的:
$ screen -r
$ kill $DPID
$ screen -d
当我是唯一的维护者时,这很好用,但现在我想让 其他人停止/重新启动该程序,无论是谁启动的。和 让事情变得更复杂的是,事实上 daemonise.sh
脚本 启动大约 16 个程序,杀死每一个程序都很麻烦 如果你不知道他们的 PID。
让另一个用户的“最佳实践”方式是什么 停止/重新启动守护进程?
我考虑过共享屏幕会话,但这听起来很老套 没有安全感。我现在想出的最好的解决方案是包装 在捕获某些信号的脚本中启动和终止:
#!/bin/bash
DPID=
trap './daemonise.sh & DPID=$!' USR1
trap 'kill $DPID' USR2 EXIT
# Ensure trapper wrapper doesn't exit:
while :; do
sleep 10000 & wait $!
done
现在,如果另一个用户需要停止守护进程而我却做不到, 她只需要知道包装器的 pid,例如 sudo Kill -s USR2 $wrapperpid。 (此外,这使得运行守护进程成为可能 重新启动后,仍然可以干净地杀死它们。)
有更好的解决方案吗?这是否存在明显的问题 我没有看到的解决方案?
(阅读 Greg 的 Bash Wiki 后,我想避免任何涉及 pgrep 或 PID 文件的解决方案……)
I have a web server where I run some slow-starting programs as daemons. These sometimes need quick restarting (or stopping) when I recompile them or switch to another installation of them.
Inspired by http://mywiki.wooledge.org/ProcessManagement, I'm writing a script
called daemonise.sh
that looks like
#!/bin/sh
while :; do
./myprogram lotsadata.xml
echo "Restarting server..." 1>&2
done
to keep a "daemon" running. Since I sometimes need to stop it, or just
restart it, I run that script in a screen session, like:
$ ./daemonise.sh & DPID=$!
$ screen -d
Then perhaps I recompile myprogram, install it to a new path, start
the new one up and want to kill the old one:
$ screen -r
$ kill $DPID
$ screen -d
This works fine when I'm the only maintainer, but now I want to let
someone else stop/restart the program, no matter who started it. And
to make things more complicated, the daemonise.sh
script in fact
starts about 16 programs, making it a hassle to kill every single one
if you don't know their PIDs.
What would be the "best practices" way of letting another user
stop/restart the daemons?
I thought about shared screen sessions, but that just sounds hacky and
insecure. The best solution I've come up with for now is to wrap
starting and killing in a script that catches certain signals:
#!/bin/bash
DPID=
trap './daemonise.sh & DPID=$!' USR1
trap 'kill $DPID' USR2 EXIT
# Ensure trapper wrapper doesn't exit:
while :; do
sleep 10000 & wait $!
done
Now, should another user need to stop the daemons and I can't do it,
she just has to know the pid of the wrapper, and e.g. sudo kill -s
. (Also, this makes it possible to run the daemons
USR2 $wrapperpid
on reboots, and still kill them cleanly.)
Is there a better solution? Are there obvious problems with this
solution that I'm not seeing?
(After reading Greg's Bash Wiki, I'd like to avoid any solution involving pgrep or PID-files …)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我推荐一个基于 PID 的初始化脚本。任何拥有该脚本 sudo 权限的人都可以启动和停止服务器进程。
I recommend a PID based init script. Anyone with sudo privileged to the script will be able to start and stop the server processes.
关于改进您的方法:确保您的
sleep
命令在sleep 10000 & 中不是明智的吗?如果您的 pidwrapper 脚本以某种方式退出, wait $!
会正确终止吗?否则,进程表中将保留一个悬空的睡眠进程相当长的一段时间。
同样,重新启动时正确终止 daemonise.sh 中的 myprogram 不是更干净吗(即,如果 daemonise.sh 收到
TERM
信号)?此外,还可以抑制作业通知消息并在杀死之前测试 pid 是否存在。
On improving your approach: wouldn't it be advisable to make sure that your
sleep
command insleep 10000 & wait $!
gets properly terminated if your pidwrapper script exits somehow?Otherwise there would remain a dangling
sleep
process in the process table for quite some time.Similarly, wouldn't it be cleaner to terminate
myprogram
indaemonise.sh
properly on restart (i. e. ifdaemonise.sh
receives aTERM
signal)?In addition, it is possible to suppress job notification messages and test for pid existence before killing.