在 Linux 中,要查看一个正在运行的二进制程序打开了哪些文件(包括文件路径),可以使用以下几种方法:
1. 使用 lsof
命令
lsof
(List Open Files)是最常用的工具,可以列出进程打开的所有文件描述符(包括普通文件、套接字、管道等)。
基本用法:
# 通过进程名查找(例如查看 nginx 打开的文件)
lsof -c <进程名> | grep -E 'REG|DIR'
# 通过进程ID(PID)查找
lsof -p <PID> | grep -E 'REG|DIR'
-c <进程名>
:按二进制文件名过滤(如nginx
、redis-server
)。-p <PID>
:直接指定进程ID。grep -E 'REG|DIR'
:筛选出普通文件(REG)和目录(DIR),排除其他类型。
输出示例:
nginx 1234 root 5r REG 8,1 1024 123456 /etc/nginx/nginx.conf
nginx 1234 root 6w REG 8,1 2048 789012 /var/log/nginx/access.log
- 第9列即为文件路径。
2. 使用 /proc/<PID>/fd/
Linux 的 /proc
虚拟文件系统存储了进程的实时信息,包括打开的文件描述符。
**操作步骤:
# 找到目标进程的 PID
pgrep <二进制名> # 例如 pgrep nginx
# 查看该 PID 打开的文件描述符链接的实际路径
ls -la /proc/<PID>/fd/
- 输出示例:
lrwx------. 1 root root 64 Jan 1 12:34 0 -> /dev/null
lrwx------. 1 root root 64 Jan 1 12:34 1 -> /var/log/nginx/error.log
lrwx------. 1 root root 64 Jan 1 12:34 5 -> socket:[123456]
- 符号链接右侧即为实际路径(非套接字或管道会显示具体路径)。
3. strace
动态跟踪文件操作
如果需要实时监控二进制程序的文件访问行为,可以用 strace
:
strace -e trace=open,openat,close,read,write <二进制命令>
- 适用场景:调试尚未启动的程序。
- 缺点:输出量大,需结合
grep
过滤:
strace -e openat <command> | grep 'openat.*='
4. pmap
查看内存映射文件
某些文件可能通过内存映射(mmap)方式打开:
pmap -x <PID> | grep -v "\[" | awk '{print $NF}' | sort | uniq
- 作用:列出进程映射的文件路径(如共享库、数据文件)。
注意事项
- 权限问题:普通用户只能查看自己的进程,需
root
权限才能查看所有进程。 - 动态加载:部分文件可能在运行时动态打开,建议结合业务逻辑分析。
- 容器环境:若程序运行在容器内,需在容器内执行上述命令或使用
docker exec/podman exec
.
自动化脚本示例
提取某进程打开的所有普通文件路径:
#!/bin/bash
PID=$(pgrep -f "<二进制名>" | head -n1)
if [ -z "$PID" ]; then
echo "Process not found."
exit
fi
echo "Files opened by PID $PID:"
lsof -p $PID | awk '$5=="REG" {print $9}' | sort | uniq
通过以上方法,可以准确获取二进制程序访问的文件资源。
内容由零声教学AI助手提供,问题来源于学员提问