watch 命令显示的 ps 结果与单独运行脚本时不同

watch 命令显示的 ps 结果与单独运行脚本时不同

这是我的脚本:

$ cat count_tomcat.sh 
ps -ef | grep tomcat| wc -l
$ ./count_tomcat.sh 
2

现在使用watch命令它有不同的结果:

$ watch ./count_tomcat.sh


Every 2.0s: ./count_tomcat.sh                                                                                                                                                                                Fri Oct 15 16:50:43 2021

5

答案1

赶紧跑:

watch -x pgrep -c -f tomcat

定期获取命令行包含tomcat.

或者

watch -x pgrep -c -x tomcat

ps -e对于其名称(不是命令行;如wrt的输出ps -ef)的进程雄猫。

或者:

watch -x pgrep -c -u tomcat

对于以用户身份运行的进程的计数tomcat(因为不清楚ps -ef您打算匹配输出的哪一列)。

对于-x,至少对于procps-ng的实现watch,我们跳过运行 shell 而是直接执行命令。

请注意,它pgrep -f tomcat不会报告自身(即使它的命令行包含tomcat),但它会计算watch命令并且不-x添加到watch,如果您的实现没有优化最后一个命令的分叉,则可能sh -c 'pgrep -f tomcat'调用watch解析该命令行。sh

watch -x pgrep -cf '[t]omcat'

会避免这种情况,因为[t]omcat模式与自身不匹配。

(如果没有-x,则必须是:

watch 'pgrep -cf "[t]omcat"'

as[x]也是一个 shell 通配符,因此需要对您的 shell 和watch运行的 shell 进行转义)

vi tomcat.conf当然,它也可以匹配运行或 的进程atomcatalog。基于命令行的匹配进程非常脆弱。您pgrep可以添加更多选项来优化过滤器并限制识别错误流程的风险。

在现代 Linux 系统上,您应该能够依赖控制组,或者查询systemd该信息(如果tomcat已正确设置为服务)。

答案2

事实证明,当您“以正常方式”运行脚本时,./count_tomcat.sh它不会生成新的 bash 进程,而只是在当前的 bash 进程中运行它。因此,输出中没有该脚本的新条目ps

当您通过 watch 运行它时,它会生成一个全新的 bash 进程,并以您的脚本作为参数。所以现在脚本(本身)出现在ps输出中。所以要注意pswatch

第二个问题:当ps在“普通” bash 脚本中运行命令时,它知道它正在“作为脚本运行”并进行完整的输出。

ps在由命令运行的脚本中运行该命令时watch,不知何故ps不知道它不在 TTY 环境中(即在脚本中),因此它将输出大小截断为恰好 80。那里有些不对劲。修复:使用ps -ww(无限宽度)iff 在手表内运行。也许还有其他方法。诡异的。

有用的是添加set -x到脚本中。

相关内容