pgrep 命令是不是有什么问题?加-f 参数 pid 每次都变

2023-07-31 14:32:38 +08:00
 dyllen

在 shell 脚本里面这样获取 pid:

pid=`pgrep $projectName`
echo "'$pid'"

发现有字符长度限制,太长返回空,后面改成这样:

pid=`pgrep -f $projectName`
echo "'$pid'"

问题来了加了-f参数后,获取到的 pid 的值变这样了:

'3054607
3206134'

取到了两个 pid 值,第一个是正确的,第二个是完全不相干的,每次还变。 然后我杀死进程之后再执行,他还是能获取的一个完全不相关的 pid 出来。

不管我要找的进程在不在他总是有值,还不一定对,我不用脚本执行,就在控制台执行单纯pgrep -f $projectName就没问题。

这什么问题?

1398 次点击
所在节点    Linux
19 条回复
lhbc
2023-07-31 14:50:13 +08:00
怀疑这么基础的软件有问题之前,还是先怀疑下你的参数和系统的进程列表比较好
你给个变量谁知道什么情况啊
lhbc
2023-07-31 14:51:52 +08:00
另外,如果同一个进程名称有多个进程,pgrep 是会获取到多个 pid 的
liuchao719
2023-07-31 15:42:41 +08:00
这个不想干的进程是不是就是 pgrep 本身?
julyclyde
2023-07-31 15:49:07 +08:00
@liuchao719 pgrep 会过滤掉 pgrep 自己的,不会发生你猜的这种情况

第二个应该是线程号
lhbc
2023-07-31 15:50:40 +08:00
@liuchao719 不会,pgrep 里有逻辑把自己的 pid 给去掉了
dyllen
2023-07-31 16:22:30 +08:00
@lhbc 我肯定是对过了,才会来发问的。

下面是我测试的内容。

我的测试脚本内容:

```shell
#!/bin/bash

set -e

pid=`pgrep -f $1`
echo "'$pid'"
```
`./test.sh abc`结果:
```shell
~$ ./test.sh abc
'3234022
3354825'

~$ ./test.sh abc
'3234022
3354899'

~$ ./test.sh abc
'3234022
3354906'
```

控制台执行的输出结果:

```shell
~$ echo `pgrep -f abc`
3234022

~$ echo `pgrep -f abc`
3234022

~$ echo `pgrep -f abc`
3234022
```

`ps -ef | grep`出来出去 grep 的进程,就一个运行进程。

这里我把名字用 abc 替换了,实际也是这么简单,英文字母下划线组成的 10 个字符长度的名字,没特殊字符。
llh880808
2023-07-31 16:30:14 +08:00
提供一个思路,我这边做实验得到的结果是
1. pgrep $name 得到 1 个结果
2. pgrep -f $name 得到 2 个结果
3. ps -ef | grep 多出来的那个 pid ,发现多出来的 pid 是 CMD 列包含`$name`字样(比如路径名包含),但并不是我预期的
4. pgrep -h 查看-f 参数的含义是“ use full process name to match”,猜想,-f 参数会使用整个进程名(包括参数)去匹配,很容易匹配到预期外的结果
dyllen
2023-07-31 16:52:36 +08:00
@llh880808 是加了-f 参数,得到两个结果,第二个完全不相干的 pid 了
Alias4ck
2023-07-31 16:55:27 +08:00
感觉是你字符串的问题你可以-l 打印完整进程名看看

dyllen
2023-07-31 16:55:43 +08:00
@llh880808 不加-f 参数,有长度限制,名称超过 15 个字符就匹配不出来了,搜索下来都是说加-f 参数解决,加了之后我发现会匹配出来两个结果。所以现在我是就截取前 15 个字符来匹配。。。这样暂时没问题。
dyllen
2023-07-31 16:58:13 +08:00
@Alias4ck

`test.sh`加了-l ,结果:

~$ ./test.sh abc
'3234022 abc
3403871 test.sh'


第二个 pid 是脚本本身。
Alias4ck
2023-07-31 17:02:43 +08:00
那就合理的解释了为啥每次都会变了 因为匹配到自身了

找到一个跟你差不多的问题
https://stackoverflow.com/questions/59790449/bash-script-strange-pgrep-behaviour
lhbc
2023-07-31 17:03:44 +08:00
./test.sh abc
这个命令本身被匹配到了
lhbc
2023-07-31 17:09:23 +08:00
不要把进程名称作为脚本的参数提交
julyclyde
2023-07-31 19:33:35 +08:00
不过这问题应该换个角度(不是可以,而是应该)
你可能需要把这个进程托管给 systemd 管理,而不是自己寨一套脚本出来
dyllen
2023-08-03 11:21:23 +08:00
@julyclyde 这又不是线上用的,就是为了方便自己开发重启应用用的,我那小脚本功能是拉取代码,编译,结束原来的进程,启动新的进程。
dyllen
2023-08-03 11:23:40 +08:00
@lhbc 这就不太好了,那只能自己再过滤一遍结果了,或者只取前 15 个字符不加-f 参数来匹配了,这样也没有问题。
julyclyde
2023-08-03 12:14:37 +08:00
@dyllen 让旧进程自己写个 pid 文件吧
dyllen
2023-08-06 11:51:57 +08:00
@julyclyde 这样也可以,pid 记录下来

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/961199

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX