微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

linux – 脚本中ps aux和`ps aux`之间的结果不同

我有一个bash脚本(ScreamDaemon.sh),其中添加一个检查,它的示例尚未运行.

numscr=`ps aux | grep ScreamDaemon.sh | wc -l`;
if [ "${numscr}" -gt "2" ]; then
  echo "an instance of ScreamDaemon still running";
  exit 0;
fi

通常,如果没有另一个脚本副本运行,ps aux | grep ScreamDaemon.sh | wc -l应该返回2(它应该找到自己和grep ScreamDaemon.sh),但它返回3.

所以,我尝试分析发生了什么,并在添加一些回声之后看到:

我已经在脚本中添加了一些行

ps aux | grep ScreamDaemon.sh
ps aux | grep ScreamDaemon.sh | wc -l
str=`ps aux | grep ScreamDaemon.sh`
echo $str
numscr=`ps aux | grep ScreamDaemon.sh | wc -l`;
echo $numscr

一个输出

pamela   27894  0.0  0.0 106100  1216 pts/1    S+   13:41   0:00 /bin/bash ./ScreamDaemon.sh
pamela   27899  0.0  0.0 103252   844 pts/1    S+   13:41   0:00 grep ScreamDaemon.sh
2
pamela 27894 0.0 0.0 106100 1216 pts/1 S+ 13:41 0:00 /bin/bash ./ScreamDaemon.sh pamela 27903 0.0 0.0 106100 524 pts/1 S+ 13:41 0:00 /bin/bash ./ScreamDaemon.sh pamela 27905 0.0 0.0 103252 848 pts/1 S+ 13:41 0:00 grep ScreamDaemon.sh
3

我还尝试在`ps aux |中添加sleep命令grep ScreamDaemon.sh;睡1m`并从并行终端看到ps aux | grep ScreamDaemon.sh显示的实例数:

[pamela@pm03 ~]$ps aux | grep ScreamDaemon.sh
pamela   28394  0.0  0.0 106100  1216 pts/1    S+   14:23   0:00 /bin/bash ./ScreamDaemon.sh
pamela   28403  0.0  0.0 106100   592 pts/1    S+   14:23   0:00 /bin/bash ./ScreamDaemon.sh
pamela   28408  0.0  0.0 103252   848 pts/9    S+   14:23   0:00 grep ScreamDaemon.sh

所以,似乎
    str =`ps aux | grep ScreamDaemon.sh`
与之相反
    ps aux | grep ScreamDaemon.sh
发现了两个ScreamDaemon.sh实例,但为什么呢?这个额外的ScreamDaemon.sh副本来自哪里?

这是pstree -ap命令的输出

  │   ├─sshd,27806
  │   │   └─sshd,27808
  │   │       └─bash,27809
  │   │           └─ScreamDaemon.sh,28731 ./ScreamDaemon.sh
  │   │               └─ScreamDaemon.sh,28740 ./ScreamDaemon.sh
  │   │                   └─sleep,28743 2m

解决方法:

为什么单个bash脚本可以在ps中多次显示

当任何隐式创建子shell的构造都在进行中时,这是典型的.例如,在bash中:

echo foo | bar

…创建一个新的shell分叉副本以运行echo,并使用自己的ps实例.同理:

( bar; echo done )

…创建一个新的子shell,子shell运行外部命令栏,然后让子shell执行echo.

同理:

foo=$(bar)

…为命令替换创建一个子shell,在那里运行bar(可能执行命令并使用子shell,但这不保证),并将其输出读入父级.

现在,这是如何回答你的问题的?因为

result=$(ps aux | grep | wc)

…在子shell中运行ps命令,它本身会创建一个额外的bash实例.

如何才能正确确保我的脚本只运行一个副本?

使用锁文件.

例如,见:

> How to prevent a script from running simultaneously?
> What is the best way to ensure only one instance of a Bash script is running?

请注意,我强烈建议使用基于flock的变体.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐