一尘不染

脚本内的ps aux和`ps aux`之间的结果不同

linux

我有一个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.shps 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

阅读 465

收藏
2020-06-07

共1个答案

一尘不染

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

当隐式创建子外壳的任何构造都在起作用时,这是典型的。例如,在bash中:

echo foo | bar

…创建一个新的shell分叉副本以运行echo,并使用其自己的ps实例。类似地:

( bar; echo done )

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

类似地:

foo=$(bar)

…创建一个用于命令替换的子shell,bar在其中运行(可能会exec“执行命令并使用该子shell,但这不能保证”),然后将其输出读入父级。

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

result=$(ps aux | grep | wc)

在subshel​​l中 运行该ps命令,后者本身会创建一个额外的bash实例。 __


如何正确确保脚本的一个副本正在运行?

使用锁定文件。

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

2020-06-07