fuser [选项] 文件名/目录名/端口号
| 选项 | 说明 |
|---|---|
-a |
显示所有指定的文件,即使它们没有被任何进程访问 |
-k |
杀死访问指定文件的所有进程(发送SIGKILL信号) |
-i |
在杀死进程前交互式询问用户确认 |
-I |
指定要发送的信号(默认SIGKILL) |
-m |
指定一个挂载点上的文件或块设备 |
-n |
选择名称空间(file, tcp, udp) |
-s |
静默模式,只显示PID |
-u |
显示进程所有者的用户名 |
-v |
详细模式,显示进程详细信息 |
-4 |
仅查找IPv4套接字 |
-6 |
仅查找IPv6套接字 |
-V |
显示版本信息 |
-h |
显示帮助信息 |
fuser输出中的字母表示进程对文件的访问类型:
| 字符 | 说明 |
|---|---|
c |
当前目录 |
e |
正在执行的程序 |
f |
打开的文件(默认不显示f) |
F |
打开的文件进行写操作 |
r |
根目录 |
m |
内存映射文件或共享库 |
. |
占位符(无特殊意义) |
# 查找使用/var/log/syslog文件的进程
fuser /var/log/syslog
# 查找使用指定目录的进程
fuser /var/log/
fuser -u /var/log/syslog
fuser -v /var/log/syslog
fuser -s /var/log/syslog
# 查找使用TCP端口80的进程
fuser -n tcp 80
fuser 80/tcp
# 查找使用UDP端口53的进程
fuser -n udp 53
fuser 53/udp
# 指定协议和端口格式
fuser 80/tcp
fuser 53/udp
# 查看IPv4和IPv6
fuser -4 -n tcp 80
fuser -6 -n tcp 80
# 强制杀死进程
fuser -k /var/log/syslog
# 交互式杀死进程(询问确认)
fuser -i -k /var/log/syslog
# 发送指定信号(如SIGTERM)
fuser -k -SIGTERM /var/log/syslog
fuser -k -15 /var/log/syslog # SIGTERM的信号编号
# 查找使用挂载点的进程
fuser -m /mnt/usb
# 查找使用块设备的进程
fuser -m /dev/sdb1
fuser -a /var/log/syslog
fuser /var/log/syslog /var/log/auth.log
# 查看进程详细信息
ps -p $(fuser -s /var/log/syslog)
# 查找并杀死所有使用端口的进程
fuser -k 8080/tcp
# 查看谁在使用mysql套接字
fuser /var/run/mysqld/mysqld.sock
$ fuser -u /var/log/syslog
/var/log/syslog: 1234(root) 5678(syslog)
这表示PID 1234(root用户)和PID 5678(syslog用户)正在使用该文件。
$ fuser -v /var/log/syslog
USER PID ACCESS COMMAND
/var/log/syslog: root 1234 F.... rsyslogd
syslog 5678 F.... systemd-journal
$ fuser -n tcp 80
80/tcp: 7890 9012
$ fuser -v 80/tcp
USER PID ACCESS COMMAND
80/tcp: root 7890 F.... nginx
www-data 9012 F.... nginx
$ fuser /var/log/
/var/log/: 1234c 5678e 9012m
其中:1234进程将/var/log/作为当前目录(c),5678进程正在执行该目录中的程序(e),9012进程内存映射了该目录中的文件(m)。
| 命令 | 主要功能 | 优点 | 缺点 |
|---|---|---|---|
fuser |
查找使用文件/端口的进程,可杀死进程 | 直接处理"设备忙"问题,可杀死进程 | 输出信息相对简单 |
lsof |
列出打开的文件和网络连接 | 信息详细,功能全面 | 输出复杂,学习曲线陡 |
ss/netstat |
网络连接统计 | 网络连接信息详细 | 不能直接处理文件锁定 |
ps + grep |
进程查找 | 灵活,可组合各种条件 | 需要较多命令组合 |
# 尝试卸载时出现错误
$ umount /mnt/usb
umount: /mnt/usb: device is busy
# 使用fuser查找占用进程
$ fuser -m /mnt/usb
/mnt/usb: 1234 5678
# 查看进程详情
$ ps -p 1234,5678
# 杀死占用进程(谨慎操作)
$ fuser -k -m /mnt/usb
# 现在可以卸载了
$ umount /mnt/usb
# Apache无法启动,80端口被占用
$ fuser 80/tcp
80/tcp: 7890
# 查看是什么进程
$ ps -p 7890
# 如果是非关键进程,可以杀死
$ fuser -k 80/tcp
# 或者使用指定信号优雅终止
$ fuser -k -TERM 80/tcp
# 删除文件时提示文件忙
$ rm important.log
rm: cannot remove 'important.log': Device or resource busy
# 查找使用该文件的进程
$ fuser important.log
important.log: 1234 5678
# 查看进程并决定处理方式
$ ps -p 1234,5678
PID TTY STAT TIME COMMAND
1234 ? Ss 0:00 /usr/sbin/rsyslogd
5678 ? S 0:00 tail -f important.log
# 如果是tail命令,可以直接终止
$ kill 5678
# 如果是系统服务如rsyslogd,需要重启服务或等待
$ systemctl restart rsyslog
# 查看所有使用/var/log目录的进程详情
fuser /var/log/ 2>/dev/null | xargs -n1 ps -p
# 查找并优雅终止使用端口的进程
fuser -k -TERM 8080/tcp
# 监控文件访问变化
watch -n 1 'fuser -v /var/log/syslog'
# 批量查找多个端口的占用情况
for port in 80 443 3306 5432; do
echo "Port $port:"
fuser $port/tcp 2>/dev/null || echo " Not in use"
done
# 查找所有使用网络端口的进程并按端口排序
for proto in tcp udp; do
for port in $(netstat -tuln | grep ":$proto" | awk '{print $4}' | cut -d: -f2 | sort -nu); do
echo "$port/$proto:"
fuser $port/$proto 2>/dev/null || echo " No process found"
done
done
-k选项杀死进程时要特别小心,可能中断重要服务-i选项交互式确认,或先查看进程详情再决定-SIGTERM而不是默认的-SIGKILLfuser命令通常包含在psmisc软件包中,大多数Linux发行版默认已安装。
# 检查是否已安装
which fuser
fuser -V
# Ubuntu/Debian安装(如果需要)
sudo apt-get install psmisc
# CentOS/RHEL/Fedora安装
sudo yum install psmisc
# Arch Linux
sudo pacman -S psmisc
# 验证安装
fuser --help
#!/bin/bash
# 安全卸载USB设备脚本
DEVICE="/mnt/usb"
LOG_FILE="/var/log/usb_unmount.log"
echo "=== USB设备卸载检查 $(date) ===" >> $LOG_FILE
# 检查设备是否挂载
if ! mountpoint -q $DEVICE; then
echo "设备 $DEVICE 未挂载" | tee -a $LOG_FILE
exit 0
fi
# 查找使用该设备的进程
PROCESSES=$(fuser -m $DEVICE 2>/dev/null)
if [ -n "$PROCESSES" ]; then
echo "以下进程正在使用 $DEVICE:" | tee -a $LOG_FILE
echo "$PROCESSES" | tee -a $LOG_FILE
# 显示进程详情
for PID in $PROCESSES; do
ps -p $PID -o pid,user,cmd >> $LOG_FILE
done
echo "尝试优雅终止进程..." | tee -a $LOG_FILE
fuser -k -TERM -m $DEVICE
# 等待进程终止
sleep 2
# 再次检查
if fuser -m $DEVICE 2>/dev/null; then
echo "仍有进程在使用设备,强制终止..." | tee -a $LOG_FILE
fuser -k -KILL -m $DEVICE
sleep 1
fi
fi
# 尝试卸载
if umount $DEVICE; then
echo "设备 $DEVICE 已成功卸载" | tee -a $LOG_FILE
else
echo "无法卸载设备 $DEVICE" | tee -a $LOG_FILE
echo "可能需要手动检查或重启系统" >> $LOG_FILE
exit 1
fi
#!/bin/bash
# 端口占用监控脚本
PORTS="80 443 22 3306 5432" # 监控的端口列表
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/port_monitor.log"
echo "=== 端口监控开始 $(date) ===" >> $LOG_FILE
for PORT in $PORTS; do
# 检查TCP端口
PROCESSES=$(fuser $PORT/tcp 2>/dev/null)
if [ -n "$PROCESSES" ]; then
echo "端口 $PORT/TCP 被以下进程使用:" >> $LOG_FILE
echo "$PROCESSES" >> $LOG_FILE
# 记录进程详情
for PID in $PROCESSES; do
ps -p $PID -o pid,user,cmd >> $LOG_FILE 2>/dev/null || echo "进程 $PID 不存在" >> $LOG_FILE
done
# 检查是否为预期进程
if ! fuser $PORT/tcp 2>/dev/null | xargs -n1 ps -p 2>/dev/null | grep -q "nginx\|apache\|ssh\|mysqld\|postgres"; then
SUBJECT="警报:端口 $PORT 被非预期进程占用"
MESSAGE="端口 $PORT/TCP 被非预期进程占用\n"
MESSAGE+="进程ID: $PROCESSES\n"
MESSAGE+="时间: $(date)\n"
echo -e "$MESSAGE" | mail -s "$SUBJECT" $ALERT_EMAIL
echo "$(date): 发送警报 - 端口 $PORT 异常" >> $LOG_FILE
fi
else
echo "端口 $PORT/TCP 未被使用" >> $LOG_FILE
fi
done
echo "=== 监控结束 ===" >> $LOG_FILE