计算shell脚本中的进程[重复]

Posted

技术标签:

【中文标题】计算shell脚本中的进程[重复]【英文标题】:count processes in shell script [duplicate] 【发布时间】:2012-10-21 20:38:40 【问题描述】:

可能重复: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

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

【问题讨论】:

您是否尝试将ps -e|grep "cntps"|grep -v grep 添加到您的脚本中以查看您正在计算哪些进程? 是的。我试过了。只是我自己的脚本的过程。 相关wiki.bash-hackers.org/howto/mutex(短版:使用系统上可用的锁定实用程序) 【参考方案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】:

首先,我建议使用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 脚本。

【讨论】:

是的。我在输入问题时错过了 wc -l。谢谢!您的回答很有帮助。【参考方案3】:

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

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

【讨论】:

以上是关于计算shell脚本中的进程[重复]的主要内容,如果未能解决你的问题,请参考以下文章

代码片段:Shell脚本实现重复执行和多进程

用于捕获进程 ID 并在存在时将其终止的 Shell 脚本[重复]

第9章:Shell脚本进程管理

shell脚本让进程在后台运行以及进程后台转前台

如何在脚本中获取进程ID

共享一个防止脚本重复启动的shell脚本