我有一个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 显示了多少个实例:
ps aux |** 内部添加 **sleep** 命令 **。 grep ScreamDaemon.sh; 睡眠1m
[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的 这个附加副本来自 何处 ?
ps aux | grep ScreamDaemon.sh
这是pstree -ap命令的输出
│ ├─sshd,27806 │ │ └─sshd,27808 │ │ └─bash,27809 │ │ └─ScreamDaemon.sh,28731 ./ScreamDaemon.sh │ │ └─ScreamDaemon.sh,28740 ./ScreamDaemon.sh │ │ └─sleep,28743 2m
ps
当隐式创建子外壳的任何构造都在起作用时,这是典型的。例如,在bash中:
echo foo | bar
…创建一个新的shell分叉副本以运行echo,并使用其自己的ps实例。类似地:
echo
( bar; echo done )
…创建一个新的子shell,让该子shell运行外部命令bar,然后让该子shell执行echo。
bar
类似地:
foo=$(bar)
…创建一个用于命令替换的子shell,bar在其中运行(可能会exec“执行命令并使用该子shell,但这不能保证”),然后将其输出读入父级。
exec
现在,这如何回答您的问题?因为
result=$(ps aux | grep | wc)
… 在subshell中 运行该ps命令,后者本身会创建一个额外的bash实例。 __
使用锁定文件。
请注意,我 强烈 建议您使用flock基于-的变体。
flock