Linux问题排查-找到偷偷写文件的进程

在 Linux 系统中,若要通过已修改的文件找到修改该文件的进程 PID,可以结合以下方法分析,具体取决于文件是否仍被进程打开或已被删除但句柄仍存在:

一、文件仍被进程打开(未删除)

如果文件当前正在被某个进程修改且未关闭/删除,可通过以下方式查找:

1. lsof 命令(推荐)

lsof(List Open Files)可列出系统中所有打开的文件及对应的进程信息。
命令格式

lsof <文件路径>

示例

lsof /var/log/syslog

输出解读

  • PID 列:修改文件的进程 PID。
  • USER 列:进程所属用户。
  • FD 列:文件描述符(u 表示读写模式,r 表示只读,w 表示写入)。
2. fuser 命令

fuser 用于查找使用指定文件的进程。
命令格式

fuser -v <文件路径>

示例

fuser -v /tmp/test.txt

输出解读

  • USER 列:进程所属用户。
  • PID 列:占用文件的进程 PID。
  • TYPE 列:文件类型(如 cwd 表示当前工作目录,txt 表示可执行文件,mem 表示内存映射)。

二、文件已被删除但进程仍持有句柄

若文件已被删除(如通过 rm 命令删除),但进程仍在写入该文件(未关闭文件句柄),此时文件在磁盘上已不可见,但可通过进程的虚拟文件系统(/proc)查看:

1. 通过 /proc/<PID>/fd 查找

每个进程的文件描述符存储在 /proc/<PID>/fd/ 目录下,即使文件已删除,仍可能存在指向该文件的句柄(显示为 (deleted))。
步骤

  1. 遍历所有进程的 fd 目录:

    for pid in /proc/[0-9]*; dols -l $pid/fd 2>/dev/null | grep "deleted" | grep "<文件名片段>"
    done
    

    (将 <文件名片段> 替换为已删除文件的部分名称,如 test.txt

  2. 示例输出

    lrwx------ 1 root root 64 Jun  5 14:30 3 -> /tmp/test.txt (deleted)
    
    • 上述输出表示 PID 对应目录下的文件描述符 3 指向已删除的 /tmp/test.txt,该进程正在写入该文件。
2. lsof 命令直接查询(支持已删除文件)

lsof 可直接列出已删除但仍被进程打开的文件:

lsof | grep "deleted" | grep "<文件名片段>"

示例输出

vim     12345  user    3r   REG  8,1  1234  56789 /tmp/test.txt (deleted)
  • PID=12345 的进程(此处为 vim)正在以只读模式(3r)打开已删除的文件。

三、通过文件修改时间和进程日志辅助定位

若无法通过上述方法直接定位(如文件已关闭且未被删除),可结合以下间接方式:

1. 查看文件修改时间

通过 stat 命令获取文件最后修改时间:

stat /path/to/file
  • 记录时间戳后,结合系统日志(如 syslogauditd)或进程监控工具(如 ps aux --sort=-etime)查找该时间段内活跃的进程。
2. 使用 auditd 审计系统

若系统启用了 auditd(审计服务),可配置规则监控文件修改事件:

  1. 添加审计规则:

    auditctl -w /path/to/file -p wa -k file_modify
    

    (监控文件的写入(w)和属性修改(a)事件)

  2. 触发修改后,查看审计日志:

    ausearch -k file_modify | grep pid
    
    • 输出中会包含修改文件的进程 PID 和用户信息。

四、总结:常用命令速查表

场景命令示例说明
文件未删除,查找进程lsof /path/to/file直接列出打开文件的进程
文件未删除,快速定位fuser -v /path/to/file显示占用文件的进程及权限
文件已删除,查找句柄`lsofgrep “deleted”
遍历进程 fd 目录for pid in /proc/[0-9]*; do ls -l $pid/fd; done手动筛查文件描述符

注意事项

  • 权限问题:部分文件(如系统文件)需 root 权限才能查看。
  • 时效性:若进程已关闭文件或重启,将无法通过上述方法定位。 这个问题下面的案例可以实现
  • 日志依赖auditd 等功能需提前配置,否则无法追溯历史修改事件。

根据文件是否被删除及当前状态,选择合适的工具组合即可高效定位修改文件的进程 PID。

案例:

现在/tmp目录被写入了一个/tmp/20250514080520642/68244ec00b4743533ed841b6 的文件,如何编写一个shell的监控程序,可以在下一次进程些文件的时候,可以获取进程信息。

在传统的 comm 命令中,-z 选项并非标准选项(可能仅在某些特定系统或版本中存在)。当出现 comm: 无效选项 -- z 错误时,说明当前系统的 comm 不支持带 NUL 分隔符的 z 参数。此时需要调整脚本逻辑,改用其他方式处理包含特殊字符(如换行符)的文件路径。以下是修改后的脚本,移除 comm -z 并改用文本行处理:

修正后的轮询监控脚本(兼容传统 comm)

#!/bin/bash# 纯 shell 实现的 /tmp 目录监控脚本(修复 comm -z 错误)
# 使用方法: ./monitor_tmp_polling.sh [轮询间隔(秒)] [输出日志文件]POLL_INTERVAL="${1:-1}"  # 默认轮询间隔 1 秒
LOG_FILE="${2:-/tmp/tmp_writes_monitor.log}"
TMP_DIR="/tmp"# 创建日志文件
touch "$LOG_FILE" || { echo "无法创建日志文件 $LOG_FILE" >&2; exit 1; }echo "=== 开始监控 $TMP_DIR 目录的写入操作 (轮询间隔: ${POLL_INTERVAL}s) ===" | tee -a "$LOG_FILE"
echo "日志文件: $LOG_FILE"
echo "按 Ctrl+C 停止监控"
echo# 初始文件列表(每行一个文件路径)
OLD_FILES=$(mktemp)
find "$TMP_DIR" -type f -print 2>/dev/null | sort > "$OLD_FILES"# 清理函数
cleanup() {rm -f "$OLD_FILES" "$NEW_FILES"echo "=== 监控已停止 ===" | tee -a "$LOG_FILE"exit
}trap cleanup SIGINT SIGTERMwhile true; do# 新文件列表(每行一个文件路径)NEW_FILES=$(mktemp)find "$TMP_DIR" -type f -print 2>/dev/null | sort > "$NEW_FILES"# 找出新增的文件(通过 comm 对比,排除已存在的文件)NEW_FILES_LIST=$(comm -13 "$OLD_FILES" "$NEW_FILES")  # 移除 -z 选项if [ -n "$NEW_FILES_LIST" ]; thentimestamp=$(date +"%Y-%m-%d %H:%M:%S")echo "[$timestamp] 检测到 $(echo "$NEW_FILES_LIST" | wc -l) 个新文件" | tee -a "$LOG_FILE"# 处理每个新增文件(逐行读取,兼容含空格的文件名)while IFS= read -r file; doecho "[$timestamp] 新文件: $file" | tee -a "$LOG_FILE"# 尝试查找打开该文件的进程lsof_output=$(lsof "$file" 2>/dev/null)if [ -n "$lsof_output" ]; then# 提取进程信息(跳过表头)pids=$(echo "$lsof_output" | awk 'NR>1 {print $2}')echo "[$timestamp] 发现 $(echo "$pids" | wc -w) 个进程正在访问该文件:" | tee -a "$LOG_FILE"echo "$lsof_output" | tee -a "$LOG_FILE"echo | tee -a "$LOG_FILE"# 为每个进程获取详细信息for pid in $pids; doecho "[$timestamp] 进程 $pid 的详细信息:" | tee -a "$LOG_FILE"ps -p "$pid" -o user,pid,ppid,cmd,%cpu,%mem,start,etime | tee -a "$LOG_FILE"# 获取进程打开的所有文件描述符echo "[$timestamp] 进程 $pid 打开的文件描述符:" | tee -a "$LOG_FILE"ls -l /proc/"$pid"/fd 2>/dev/null | tee -a "$LOG_FILE"echo | tee -a "$LOG_FILE"doneelseecho "[$timestamp] 未找到访问该文件的进程 (可能已关闭文件句柄)" | tee -a "$LOG_FILE"echo | tee -a "$LOG_FILE"fidone <<< "$NEW_FILES_LIST"fi# 更新文件列表mv "$NEW_FILES" "$OLD_FILES"# 等待下一个轮询周期sleep "$POLL_INTERVAL"
done
使用说明

与之前的脚本相同,直接运行即可:

chmod +x monitor_tmp_polling.sh
./monitor_tmp_polling.sh  # 默认轮询间隔 1 秒,日志存于 /tmp/tmp_writes_monitor.log

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/81493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

More Effective C++:改善编程与设计(下)

目录 条款19:了解临时对象的来源 条款20:协助完成“返回值优化” 条款21:利用重载技术避免隐式类型转换 条款22:考虑以操作符复合形式&#xff08;op&#xff09;取代其独身形式&#xff08;op&#xff09; 条款23:考虑使用其他程序库 条款24:了解virtual functions、mul…

VTK|类似CloudCompare的比例尺实现2-vtk实现

文章目录 实现类头文件实现类源文件调用逻辑关键问题缩放限制问题投影模式项目git链接实现类头文件 以下是对你提供的 ScaleBarController.h 头文件添加详细注释后的版本,帮助你更清晰地理解每个成员和方法的用途,尤其是在 VTK 中的作用: #ifndef SCALEBARCONTROLLER_H #de…

PostgreSQL 联合索引生效条件

最近面试的时候&#xff0c;总会遇到一个问题 在 PostgreSQL 中&#xff0c;联合索引在什么条件下会生效&#xff1f; 特此记录~ 前置信息 数据库版本 PostgreSQL 14.13, compiled by Visual C build 1941, 64-bit 建表语句 CREATE TABLE people (id SERIAL PRIMARY KEY,c…

SpringBoot项目里面发起http请求的几种方法

在Spring Boot项目中发起HTTP请求的方法 在Spring Boot项目中&#xff0c;有几种常用的方式可以发起HTTP请求&#xff0c;以下是主要的几种方法&#xff1a; 1. 使用RestTemplate (Spring 5之前的主流方式) // 需要先注入RestTemplate Autowired private RestTemplate restT…

《Python星球日记》 第90天:微调的概念以及如何微调大模型?

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、微调原理1. 什么是大模型微调?2. 为什么需要微调?3. 微调的基本流程4. 微调策略分类二、LoRA(Low-Rank Adaptation)技术详解1. LoRA的核…

机器学习-人与机器生数据的区分模型测试 - 模型融合与检验

模型融合 # 先用普通Pipeline训练 from sklearn.pipeline import Pipeline#from sklearn2pmml.pipeline import PMMLPipeline train_pipe Pipeline([(scaler, StandardScaler()),(ensemble, VotingClassifier(estimators[(rf, RandomForestClassifier(n_estimators200, max_de…

怎样免费开发部署自己的网站?

要免费开发自己的网站&#xff0c;您可以根据自己的技术水平和需求选择以下两种主要方式&#xff1a; 零基础用户&#xff1a;建议使用如WordPress.com、Weebly、Strikingly等平台&#xff0c;快速搭建网站。 有一定技术基础的用户&#xff1a;可选择自行开发网站&#xff0c;…

调用百度云API机器翻译

新建Python文件&#xff0c;叫 text_translator.py 输入 import requests import jsonAPI_KEY "glYiYVF2dSc7EQ8n78VDRCpa" # 替换为自己的API Key SECRET_KEY "kUlhze8OQZ7xbVRp" # 替换为自己的Secret Keydef main():# 选择翻译方向while True:di…

OpenAI与微软洽谈新融资及IPO,Instagram因TikTok流失四成用户

OpenAI与微软洽谈新融资及IPO 据悉&#xff0c;OpenAI 正与微软洽谈新融资及筹备 IPO&#xff0c;关键问题是微软在 OpenAI 重组后的股权比例。微软已投资超 130 亿美元&#xff0c;双方修订 2019 年合同&#xff0c;微软拟弃部分股权换新技术访问权。OpenAI 上周放弃了有争议转…

git工具使用详细教程-------命令行和TortoiseGit图形化

下载 git下载地址&#xff1a;https://git-scm.com/downloads TortoiseGit&#xff08;图形化工具&#xff09;下载地址&#xff1a;https://tortoisegit.org/download/ 认识git结构 工作区&#xff1a;存放代码的地方 暂存区&#xff1a;临时存储&#xff0c;将工作区的代码…

构建RAG混合开发---PythonAI+JavaEE+Vue.js前端的实践

7GB显存如何部署bf16精度的DeepSeek-R1 70B大模型&#xff1f;-CSDN博客 服务容错治理框架resilience4j&sentinel基础应用---微服务的限流/熔断/降级解决方案-CSDN博客 conda管理python环境-CSDN博客 快速搭建对象存储服务 - Minio&#xff0c;并解决临时地址暴露ip、短…

【Java ee初阶】jvm(3)

一、双亲委派机制&#xff08;类加载机制中&#xff0c;最经常考到的问题&#xff09; 类加载的第一个环节中&#xff0c;根据类的全限定类名&#xff08;包名类名&#xff09;找到对应的.class文件的过程。 JVM中进行类加载的操作&#xff0c;需要以来内部的模块“类加载器”…

wps excel将表格输出pdf时所有列在一张纸上

记录&#xff1a;wps excel将表格输出pdf时所有列在一张纸上 1&#xff0c;调整缩放比例&#xff0c;或选择将所有列打印在一页 2&#xff0c;将表格的所有铺满到这套虚线

分布式微服务系统架构第134集:笔记1运维服务器经验,高并发,大数据量系统

加群联系作者vx&#xff1a;xiaoda0423 仓库地址&#xff1a;https://webvueblog.github.io/JavaPlusDoc/ https://1024bat.cn/ https://github.com/webVueBlog/fastapi_plus https://webvueblog.github.io/JavaPlusDoc/ ✅ 一、查看端口是否被占用的常用命令 1️⃣ lsof 命令&…

IS-IS 中间系统到中间系统

前言&#xff1a; 中间系统到中间系统IS-IS&#xff08;Intermediate System to Intermediate System&#xff09;属于内部网关协议IGP&#xff08;Interior Gateway Protocol&#xff09;&#xff0c;用于自治系统内部 IS-IS也是一种链路状态协议&#xff0c;使用最短路径优先…

前端安全:XSS、CSRF 防御与最佳实践

引言 随着互联网应用的普及&#xff0c;前端安全问题日益凸显。作为开发者&#xff0c;了解并防范常见的安全威胁至关重要。本文将深入探讨两种最常见的前端安全威胁&#xff1a;跨站脚本攻击&#xff08;XSS&#xff09;和跨站请求伪造&#xff08;CSRF&#xff09;&#xff…

uniapp 弹窗封装(上、下、左、右、中五个方位)

无脑复制即可&#xff01;&#xff01;&#xff01; <template><view><viewv-if"mask"class"tui-drawer-mask":class"{ tui-drawer-mask_show: visible }":style"{ zIndex: maskZIndex }"tap"handleMaskClick&qu…

Axure制作可视化大屏动态滚动列表教程

在可视化大屏设计中&#xff0c;动态滚动列表是一种常见且实用的展示方式&#xff0c;能够有效地展示大量信息。本文将详细介绍如何使用Axure制作一个动态滚动的列表展示模块。 一、准备工作 打开Axure软件&#xff1a;确保你已经安装并打开了Axure RP软件。创建新项目&#x…

零基础玩转Apache Superset可视化部署

根据官方Quick Start Guide&#xff0c;你可以按照以下步骤进行部署&#xff1a; 1. 确认环境2. 获取代码3. 获取官方最新代码4. 启动服务5. 访问Superset Web界面6. 接入数据源 前提条件&#xff1a; dockerdocker compose 1. 确认环境 安装Docker和Docker Compose 确保你…

服务器数据恢复—XFS文件系统分区消失的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 服务器上有一组由raid卡组建的raid5磁盘阵列。上层安装linux才做系统&#xff0c;采用XFS文件系统&#xff0c;划分了3个分区。 管理员将服务器的操作系统重装后&#xff0c;发现服务器上的分区发生了改变&#xff1a;一个分区消失&am…