ps -ef 不显示完整路径是因为其 command 列仅显示 argv[0](命令名或截断路径),真实可执行文件路径需通过 /proc/pid/exe 符号链接获取,该链接由内核维护、不可篡改。

ps -ef 本身不显示进程的完整路径,它只列出启动命令(可能被截断)、用户、PID、PPID 和启动时间等基本信息。想拿到真实可执行文件的绝对路径,必须配合 /proc/PID/exe。
为什么 ps -ef 看不到完整路径
ps -ef 输出的 COMMAND 列是进程的 argv[0],也就是程序启动时传入的第一个参数,通常只是命令名(如 nginx、java),不是路径;即使写了路径(如 /usr/bin/python3),也可能被内核截断或被 shell 重命名(比如用 exec -a 伪造)。
真正可靠的路径藏在 /proc/<pid>/exe</pid> —— 这是一个指向可执行文件的符号链接,由内核在进程启动时自动建立,不会被用户篡改。
查完整路径的两步实操法
以查找正在运行的 redis-server 的真实路径为例:
- 先用
ps -ef | grep redis-server找出 PID(注意过滤掉grep自身,加-v grep更稳妥) - 再用
ls -l /proc/<pid>/exe</pid>查看软链接目标
例如:
ps -ef | grep redis-server | grep -v grep root 44446 1 0 Apr15 ? 00:01:23 redis-server *:6379 <p>ls -l /proc/44446/exe lrwxrwxrwx. 1 root root 0 Apr18 04:00 /proc/44446/exe -> /usr/local/bin/redis-server</p>
输出末尾的 -> /usr/local/bin/redis-server 就是你要的完整路径。
注意子进程和主进程的路径差异
某些服务(如 Java 应用、Nginx、Supervisor 管理的服务)会 fork 出多个进程,主进程(PID 来自 systemctl show --property MainPID)往往只是管理器,真正干活的是子进程。它们的 /proc/PID/exe 可能完全不同:
- Nginx master 进程的
exe指向/usr/sbin/nginx - Nginx worker 进程的
exe也指向同一个/usr/sbin/nginx(共享二进制) - 但 Java 应用如果由
sh start.sh启动,主进程exe是/bin/bash,而子进程(java -jar xxx.jar)的exe才是/usr/lib/jvm/java-17-openjdk-amd64/bin/java
所以别只查第一个 PID,用 ps --forest -o pid,comm -g <mainpid></mainpid> 看清进程树,再对关键子进程查 /proc/PID/exe。
常见陷阱与绕过方法
直接 ls -l /proc/<pid>/exe</pid> 失败?常见原因:
-
No such file or directory:进程已退出,但 PID 还没被回收(/proc/<pid></pid>目录消失) -
Permission denied:非 root 用户查其他用户的进程(如普通用户查 root 的 redis),需提权或换用户 -
ls: cannot access '/proc/12345/exe': No such file or directory:该进程是内核线程(没有用户态可执行文件),exe不存,此时comm或cmdline更有意义 - 看到
(deleted)后缀:可执行文件已被删除,但进程还在运行(常见于升级后未重启服务),路径仍有效,只是磁盘上文件已 unlink
如果权限受限又无法切 root,可尝试读 /proc/<pid>/cmdline</pid>(用 cat /proc/<pid>/cmdline | tr '\0' ' '</pid> 转义)——虽然不保证是真实路径,但常含启动脚本位置,比如 /opt/myapp/start.sh。











