如何指定要像shell脚本中的node bnlserver.js那样执行的命令
尝试编写作为cron作业运行的shell脚本,以确保bnlserver.js仍在运行,如果没有,则重新启动 我试过这个:如何指定要像shell脚本中的node bnlserver.js那样执行的命令,shell,Shell,尝试编写作为cron作业运行的shell脚本,以确保bnlserver.js仍在运行,如果没有,则重新启动 我试过这个: #!/bin/sh # this script checks to see if the "node bnlserver.js" program is running # and restarts it if not ps -ef | grep bnlserver.js if [ $? -ne 0 ] then node | bnlserver.js fi e
#!/bin/sh
# this script checks to see if the "node bnlserver.js" program is running
# and restarts it if not
ps -ef | grep bnlserver.js
if [ $? -ne 0 ]
then
node | bnlserver.js
fi
exit
但它不起作用。我糟糕的shell脚本。我相信你们知道怎么做。
那么我该如何修复它呢?谢谢你的帮助。像这样的东西
#!/bin/sh
if ! ps -ef | grep -q "[b]nlserver[.]js"; then
node bnlserver.js
fi
语法有点简洁,但需要精确。grep-q
命令将测试匹配,并在第一次匹配时退出。模式“[b]nlserver[.]js”
设计为永远不会与grep搜索本身匹配
在有pgrep
可用的平台上,这可以提高效率
注意:感谢Charles Duffy对该代码进行了重大改进。然而,他的帮助并不支持这种方法——他更喜欢使用supervise、forever或runit。您至少需要删除第二个管道(
|
)。您可能需要指定节点脚本的路径或完整路径。除此之外,它看起来还不错(不过使用cron并不是最好的解决方案,使用“supervise”或“forever”()更好。supervise、forever、runit、daemontools、upstart、systemd、launchd,或者(就此而言)在/etc/inittab
中的一个条目,如果您有老式的SysV init。。。说真的,您的操作系统已经有了一些东西可以为您完成这项工作,而且比cronnedshell脚本做得好得多。不要重新发明这个轮子。请参阅上的脚本,以了解这有多容易--如果您使用运行它
,您的脚本只能包含exec node bnlserver.js
(在#!/bin/sh
行之后),就是这样--运行它
将确保一次只运行该进程的一个副本,如果失败,请重新启动它。相反,您拥有的是难以置信的脆弱--vim bnlserver.js
会告诉ps | grep bnlserver.js
,即使进程已关闭,您的进程仍在运行。顺便说一句,您根本不需要在脚本结束时退出;shell在不使用exit
命令的情况下所做的事情与在未传递任何参数的情况下使用exit
所做的事情完全相同(两者都以要运行的最新命令的状态退出)。首先,您将节点的输出输送到bnlserver.js
,这肯定是错误的。第二,您在当前编写的答案中并没有实际使用grep-c
(这会导致错误)。第三,grep-c
是愚蠢的,因为你只想知道答案是零还是一个或多个grep-q
将更有效地为您提供该答案,因为它在找到第一个匹配项时立即退出,而不需要读取其余的输入来生成计数。第四,您的测试语法错误-1
和结束]
之间需要有一个空格。感谢您的反馈。实际上,从修复grep
语法的角度来看,您可能需要类似的东西:if ps-ef | grep-q bnlserver.js;然后
——使用[]
和子shell将导致测试始终返回false,因为grep-q
仅通过退出状态而不是通过stdout传递其结果。避免那些额外的组件是更有效的,除了一个更少的Foo/WaIT()循环。也就是说,如果针对可用的平台,可以考虑使用<代码> PGRP< <代码>,而不是<代码> PS > GRP< <代码>,这将进一步提高正确性和效率。(这也避免了grep
命令本身出现在ps
的输出中,后者是误报的常见来源;否则,您可能会为[b]nlserver[.]js
或与自身不匹配的正则表达式grep;[.]
还阻止除文本
以外的字符匹配——就像在正则表达式中,
表示任何字符,因此默认情况下,grep foo.js
允许(比如,fooejs
匹配)。