计算shell脚本中的进程

时间:2012-11-01 09:18:17

标签: linux bash

  

可能重复:
  Quick-and-dirty way to ensure only one instance of a shell script is running at a time

我是shell脚本的新手。

我想做的是避免运行脚本的多个实例。

我有这个shell脚本cntps.sh

#!/bin/bash
cnt=`ps -e|grep "cntps"|grep -v "grep"`
echo $cnt >> ~/cntps.log
if [ $cnt < 1 ];
then 
    #do something.
else
    exit 0
fi

如果我以这种方式运行它$./cntps.sh,它会回应2

如果我以这种方式$. ./cntps.sh运行它,它会回显0

如果我用crontab运行它,它会回复3

有人可以向我解释为什么会这样吗? 什么是避免运行脚本的多个实例的正确方法?

3 个答案:

答案 0 :(得分:1)

首先,我建议使用pgrep而不是此方法。其次,我假设您错过了一个wc -l来计算脚本中的实例数

回答你的计算问题:

  

如果我以这种方式$./cntps.sh运行它,它会回显2

这是因为反引号调用:ps -e ...正在触发子shell,也称为cntps.sh,这会触发两个项目

  

如果我以这种方式$. ./cntps.sh运行它,它会回显0

这是因为您没有运行,但实际上是将其发送到当前运行的shell中。这导致没有名称cntps

运行的脚本副本
  

如果我使用crontab运行它,它会回显3

调用中的两个,一个来自crontab调用本身,它产生sh -c 'path/to/cntps.sh'

请参阅this question了解如何执行单实例shell脚本。

答案 1 :(得分:1)

我稍微更改了命令,将ps输出到日志文件,这样我们就可以看到发生了什么。

cnt=`ps -ef| tee log | grep "cntps"|grep -v "grep" | wc -l`

这就是我所看到的:

32427 -bash
  20430 /bin/bash ./cntps.sh
    20431 /bin/bash ./cntps.sh
      20432 ps -ef
      20433 tee log
      20434 grep cntps
      20435 grep -v grep
      20436 wc -l

如您所见,我的终端shell(32427)生成一个新shell(20430)来运行该脚本。然后该脚本生成另一个子shell(20431)以进行命令替换(`ps -ef | ...`)。

所以,两个人的计数是由于:

  20430 /bin/bash ./cntps.sh
    20431 /bin/bash ./cntps.sh

在任何情况下,这都不是确保只有一个进程在运行的好方法。请改为查看SO question

答案 2 :(得分:0)

使用“锁定”文件作为互斥锁。

if(exists("lock") == false)
{
    touch lock file // create a file named "lock" in the current dir
    execute_script_body // execute script commands
    remove lock file // delete the file
}
else
{
    echo "another instance is running!"
}

exit