有一个业务脚本,用lua写的,运行在debian linux下面,要求不可以启动多次。
linux下控制一个程序不可以启动多次方法挺多,这一次用了从ps读进程的方法。
很简单,只要一条语句,而且不需要特殊的权限,普通用户就可以使用。
os.execute(“test (psax|grepluatest.lua|grep" role="presentation" style="position: relative;">(psax|grepluatest.lua|grep(which lua)|wc -l) -eq 1”)
判断这个函数返回值是不是为0就可以了,为0表示正常,即只有一个实例在运行。
简单解释一下。
()是取括号里命令执行的结果。psax是取当前系统正在运行的进程。|是管道,就是把前面一个命令的输出重定向到后一个命令的输入。grepluatest.lua就是找出psax的结果中包含luatest.lua的行,当然,不同的脚本要换成相应脚本的名字。whichlua的意思是找出lua在哪个目录下,或者也可以直接写成/usr/bin/lua。grep" role="presentation" style="position: relative;">()是取括号里命令执行的结果。psax是取当前系统正在运行的进程。|是管道,就是把前面一个命令的输出重定向到后一个命令的输入。grepluatest.lua就是找出psax的结果中包含luatest.lua的行,当然,不同的脚本要换成相应脚本的名字。whichlua的意思是找出lua在哪个目录下,或者也可以直接写成/usr/bin/lua。grep(which lua)的意思是找出其中包含lua解释器的行,如果不加这一条的话会有干扰。还是看个例子吧。
建立一个文件luatest.lua:
!/usr/bin/lua
os.execute(“ps ax|grep luatest.lua”)
执行一下./luatest.lua,结果是这样的
3331 pts/0 S+ 0:00 /usr/bin/lua ./luatest.lua
3332 pts/0 S+ 0:00 sh -c ps ax|grep luatest.lua
3334 pts/0 S+ 0:00 grep luatest.lua
也就是说我们用grep检查的命令也会被ps列出来,这样一个实例就会有多条了,不符合我们的要求。那是不是我们检查一下应该有3行数据就是说明只有单一实例呢?也不行。除了grep会带来干扰,如果在crontab里调用这个脚本也会有干扰,如果在远程机器用ssh调用也会有干扰。所以我们必须把干扰去掉。
这就是为什么要加上grep (whichlua)的原因,加上这一行,就可以把多余的过滤掉,只剩下一行。再用os.execute(“psax|grepluatest.lua|grep" role="presentation" style="position: relative;">(whichlua)的原因,加上这一行,就可以把多余的过滤掉,只剩下一行。再用os.execute(“psax|grepluatest.lua|grep(which lua)”)测试一下,得到
3606 pts/0 S+ 0:00 /usr/bin/lua ./luatest.lua
这下差不多了,最后一个wc -l是统计行数,这样获得的结果就是当前进程中此脚本运行的数量,这个数量用test -eq 1来判断是不是为1,如果为1,说明当前只有一个脚本的实例在运行,整个命令执行成功,返回码为0,这时os.execute的返回值也为0,可以用lua直接判断了。