我正在尝试确保脚本仍在开发服务器上运行。它整理统计数据并提供一个网络服务,因此它应该持续存在,但是每天几次,它会因为未知原因而消失。当我们注意到我们再次启动它时,但是后面的一个痛苦,一些用户没有权限(或技术诀窍)启动它。
我的程序员想要花几个小时来解决问题的根源但是我这个忙碌的人认为必须有一种简单的方法来检测应用程序是否没有运行,然后重新启动它。
我知道我可以 cron-script ps通过grep:
ps -A | grep appname
但同样,那是我生命中的另一个小时浪费在做一些必须已经存在的事情上...是不是我可以传递可执行文件(可选择带参数)的预制应用程序,这将使进程无限期地运行?
如果它有任何区别,那就是Ubuntu。
答案 0 :(得分:73)
我在cron中使用了一个简单的脚本来确保程序正在运行。如果不是,那么它将启动它。这可能不是您正在寻找的完美解决方案,但它很简单且效果很好。
#!/bin/bash
#make-run.sh
#make sure a process is always running.
export DISPLAY=:0 #needed if you are running a simple gui app.
process=YourProcessName
makerun="/usr/bin/program"
if ps ax | grep -v grep | grep $process > /dev/null
then
exit
else
$makerun &
fi
exit
然后每分钟或每5分钟添加一个cron作业。
答案 1 :(得分:40)
Monit非常适合:)
您可以编写简单的配置文件,告诉monit观看,例如TCP端口,PID文件等
monit将运行您指定的命令,当它正在监视的进程不可用/使用太多内存/将CPU挂起太久/等时。它还会弹出一个电子邮件提醒,告诉您发生了什么以及它是否可以采取任何措施。
我们使用它来保持我们网站的负载运行,同时在出现问题时给我们提前预警。
- 忠实的员工,Monit
答案 2 :(得分:36)
注意:Upstart处于维护模式,Ubuntu使用systemd为abandoned。应该检查systemd'manual以获取有关如何编写服务定义的详细信息。
由于您使用的是Ubuntu,因此您可能会对已取代传统Upstart的sysV init感兴趣。一个关键功能是,如果服务意外死亡,它可以重新启动服务。 Fedora已经进入新贵阶段,而Debian正处于试验阶段,因此值得深入研究。
但这种情况可能有点过分,因为cron脚本需要2分钟才能实现。
#!/bin/bash
if [[ ! `pidof -s yourapp` ]]; then
invoke-rc.d yourapp start
fi
答案 3 :(得分:19)
如果您使用的是基于systemd的发行版(如Fedora和最近的Ubuntu发行版),则可以使用systemd的"Restart" capability来获取服务。如果需要由特定用户管理和运行,它可以设置为系统服务或用户服务,这在OP的特定情况下更有可能。
重新启动选项takes one of no
,on-success
,on-failure
,on-abnormal
,on-watchdog
,on-abort
或{{ 1}}。
要以用户身份运行,只需将以下文件放入always
:
~/.config/systemd/user/something.service
然后:
[Unit]
Description=Something
[Service]
ExecStart=/path/to/something
Restart=on-failure
[Install]
WantedBy=graphical.target
不需要root权限/修改系统文件,不需要cron作业,无需安装,灵活如地狱(请参阅文档中的所有相关服务选项)。
有关使用每用户systemd实例的详细信息,另请参阅https://wiki.archlinux.org/index.php/Systemd/User。
答案 4 :(得分:8)
将你的跑步放在一个循环中 - 所以当它退出时,它会再次运行......而(真){运行我的应用..}
答案 5 :(得分:8)
我用过cron“killall -0 programname || /etc/init.d/programname start”。如果进程不存在,kill将出错。如果它确实存在,它将向进程发送一个空信号(内核将忽略它并且不会打扰传递。)
这个成语很容易记住(恕我直言)。通常我会使用它,而我仍在尝试发现服务本身失败的原因。恕我直言,一个程序不应该意外地消失:)
答案 6 :(得分:3)
由于某些原因,我无法让 Chris Wendt 解决方案工作,而且很难调试。这一个几乎相同,但更容易调试,从模式匹配中排除bash。要调试只运行:Private Sub WriteToCsv(table As DataTable, path As String)
Dim lines As New List(Of String)
For Each row As DataRow In table.Rows
lines.Add(String.Format("""{0}"",{1},{2:yyyy-MM-dd},""{3}""",
row(0),
row(1),
row(2),
row(3)))
Next
IO.File.WriteAllLines(path, lines)
End Sub
。在以下使用mysql-server的示例中,只需为您的进程替换bash ./root/makerun-mysql.sh
和process
的变量值。
makerun
):nano /root/makerun-mysql.sh
通过添加适当的文件权限(即#!/bin/bash
process="mysql"
makerun="/etc/init.d/mysql restart"
if ps ax | grep -v grep | grep -v bash | grep --quiet $process
then
printf "Process '%s' is running.\n" "$process"
exit
else
printf "Starting process '%s' with command '%s'.\n" "$process" "$makerun"
$makerun
fi
exit
)
然后将其添加到您的crontab(chmod 700 /root/makerun-mysql.sh
):
crontab -e
答案 7 :(得分:2)
来自supervise
的{{1}}工具将是我的偏好 - 但Dan J Bernstein撰写的所有内容都是我的偏好:)
http://cr.yp.to/daemontools/supervise.html
您必须为应用程序启动脚本创建特定的目录结构,但它使用起来非常简单。
答案 8 :(得分:1)
这是DMD(守护程序监视守护程序)的工作。周围有几个;但我通常只编写一个脚本来检查守护进程是否正在运行,如果没有则运行,并将其放入cron中以便每分钟运行一次。
答案 9 :(得分:1)
首先,你如何开始这个应用程序?它会将自己分解为背景吗?是从nohup开始的吗?&等等?如果是后者,请检查为什么它在nohup.out中死亡,如果是第一个,则构建日志记录。
关于你的主要问题:你可以在后台运行它,或者在后台运行另一个进程(不是最佳选择)并在bashscript中使用pidof,这很容易:
if [ `pidof -s app` -eq 0 ]; then
nohup app &
fi
答案 10 :(得分:1)
你可以把它变成一个从inittab启动的服务(虽然有些Linux已经转移到了/etc/event.d中更新的东西)。这些内置系统可确保您的服务在不编写自己的脚本或安装新内容的情况下继续运行。
答案 11 :(得分:1)
查看"Unix Hater's Handbook"第9章(p197左右)中引用的“nanny
”(PDF格式的书籍的几个来源之一)。
答案 12 :(得分:1)
一个很好,简单的方法如下:
如果它没有运行它将启动,如果它正在运行它不会。无论如何,您的服务器将始终处于运行状态。
答案 13 :(得分:0)
我认为更好的解决方案就是测试功能。例如,如果你必须测试一个apache,那么仅仅测试是否存在系统上的“apache”进程是不够的。
如果您想测试apache是否正常,请尝试下载一个简单的网页,并测试您的唯一代码是否在输出中。
如果没有,请使用-9终止apache,然后重新启动。并将邮件发送到根目录(这是转发到公司/服务器/项目根目录的邮件地址)。
答案 14 :(得分:0)
它更简单:
static __inline__ uint64_t mulhilo64(uint64_t a, uint64_t b, uint64_t *c){
return _mulx_u64(a, b, &c);
}
你必须记住,但要确保processname是唯一的。
答案 15 :(得分:0)
一个人可以像这样安装对cronjob的详细监视:
crontab -l> crontab; echo -e'* * * * *导出DISPLAY =“:0.0” && “ eiskaltdcpp-qt”“ transmission-gtk”“尼古丁”中的应用;执行ps aux | grep -v grep | grep“ $ app”;完成||“ $ app”&'>> crontab; crontab crontab
缺点是必须在ps aux|grep "appname"
输出中找到您输入的应用程序名称,并且必须同时使用该名称启动:"appname" &