pidof不支持按完整路径精确匹配,仅基于comm名查找;推荐用pgrep -f加锚定正则(如pgrep -f '^/usr/local/bin/myapp(\s|$)')或遍历/proc/[PID]/exe验证真实路径。

pidof 本身不支持按可执行文件的完整路径精确匹配,它只根据进程的 comm 名(即命令名,通常是二进制 basename)查找,因此直接使用 pidof /usr/local/bin/myapp 是无效的,会报错或无输出。
用 pgrep -f 配合完整路径匹配(推荐)
更可靠的方式是用 pgrep 结合 -f 选项,匹配进程的完整命令行(cmdline),再用正则或字符串锚定确保路径精确:
-
pgrep -f '^/usr/local/bin/myapp(\s|$)'—— 使用正则确保以该路径开头,后接空格或结尾,避免匹配到/usr/local/bin/myapp_old或参数中含路径的情况 - 若路径含特殊字符(如点、斜杠),需对正则转义,或改用固定字符串匹配:
pgrep -f -- '/usr/local/bin/myapp' | xargs -r ps -o pid= -o args= | awk '$2 == "/usr/local/bin/myapp" {print $1}' - 注意:部分系统上
ps -o args=可能截断长命令行,建议用ps -o cmd=或直接读取/proc/$PID/cmdline
用 ps + grep 安全提取 PID(兼容性强)
适用于老旧系统或需最大兼容性的场景:
-
ps -eo pid,comm,args | awk '$3 == "/usr/local/bin/myapp" {print $1}'—— 精确匹配第三列(args)为该路径(要求进程未带参数启动) - 更稳妥:
ps -eo pid,args | while read pid args; do [ -n "$args" ] && [ "$args" = "/usr/local/bin/myapp" ] && echo $pid; done - 若进程带参数,应匹配
args开头:ps -eo pid,args | awk '$2 ~ /^\/usr\/local\/bin\/myapp(\s|$)/ {print $1}'
用 /proc 遍历验证可执行路径(最准确)
绕过命令行欺骗,直接检查内核记录的真实可执行文件路径:
for pid in /proc/[0-9]*; do [ -f "$pid/exe" ] && exe=$(readlink -e "$pid/exe" 2>/dev/null) && [ "$exe" = "/usr/local/bin/myapp" ] && echo ${pid#/proc/}; done- 优点:完全防伪造,不受 argv 修改或脚本包装影响;缺点:需要 root 权限才能读取所有进程的
exe链接(普通用户只能看到自己进程) - 非 root 场景可加
2>/dev/null忽略权限错误,仅返回有权限访问的匹配项
实际使用建议
日常运维优先用 pgrep -f 加锚定正则,兼顾简洁与准确性;关键服务清理前,建议先用 ps -p $(上述命令) -f 人工确认进程详情;切勿在未验证时直接拼接 kill,可先用 xargs echo kill 预览。


















