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

标签 linux bash shell

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

因此,我尝试分析发生了什么,并在添加一些 echo 后看到:

我在脚本中添加了一些行

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; sleep 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辅助| grep ScreamDaemon.sh` 与之相反 ps 辅助 | 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 运行外部命令 bar,然后让子 shell 执行 echo

类似地:

foo=$(bar)

...为命令替换创建子 shell,在其中运行 bar(可能 exec'ing 命令并使用子 shell,但这不能保证) ,并将其输出读入父级。

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

result=$(ps aux | grep | wc)

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


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

使用锁文件。

例如:

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

关于linux - 脚本中 ps aux 和 `ps aux` 之间的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34567154/

相关文章:

c++ - 使用 `libopencv_ffmpeg.so` 在 Linux 上构建 OpenCV 2.4.11

c - 是否有不受 SIGTERM 影响的进程?

java - 如何使用java访问unix shell特殊变量

linux - 对脚本的一点帮助

shell - 如何从 Heroku 获取所有 ENV 变量(包括内部变量)

linux - 从在 Windows 上运行的 Jenkins 在 Linux 上创建 docker 容器

linux - 如果动态加载程序找不到库,我可以运行可执行文件吗?

c - 用于编译的 GCC 链接库

bash - 在 bash 中使用循环将进程替换添加到命令行

regex - 在bash中替换密码参数值