本文目录导读:

#!/bin/bash
# 不活跃阈值(秒)
INACTIVE_LIMIT=300 # 5分钟
CHECK_INTERVAL=60 # 检查间隔(秒)
# 需要监控的程序列表(进程名或完整路径)
TARGET_PROGRAMS=(
"firefox"
"google-chrome"
"code" # VS Code
)
# 获取当前活跃窗口的进程信息
get_active_process() {
# 方法1:使用xdotool(需要安装)
if command -v xdotool &> /dev/null; then
active_pid=$(xdotool getactivewindow getwindowpid)
if [ -n "$active_pid" ]; then
ps -p "$active_pid" -o comm= 2>/dev/null
return
fi
fi
# 方法2:使用wmctrl(备用方案)
if command -v wmctrl &> /dev/null; then
active_window=$(wmctrl -lp | grep "$(xdotool getactivewindow getwindowname)" | awk '{print $3}')
if [ -n "$active_window" ]; then
ps -p "$active_window" -o comm= 2>/dev/null
return
fi
fi
echo ""
}
# 获取进程的最后活动时间
get_last_active_time() {
local process_name=$1
# 使用/proc文件系统获取进程启动时间
local pids=$(pgrep -x "$process_name" 2>/dev/null)
if [ -n "$pids" ]; then
for pid in $pids; do
# 获取进程启动时间(Unix时间戳)
local start_time=$(stat -c %Y /proc/"$pid" 2>/dev/null)
# 获取进程的tty活动时间(如果有)
local last_access=$(stat -c %X /proc/"$pid" 2>/dev/null)
echo "$last_access"
return
done
fi
echo ""
}
# 主检查循环
echo "启动不活跃程序监控..."
echo "不活跃阈值:${INACTIVE_LIMIT}秒"
echo "检查间隔:${CHECK_INTERVAL}秒"
echo "监控程序:${TARGET_PROGRAMS[*]}"
echo "----------------------------------------"
while true; do
current_time=$(date +%s)
active_process=$(get_active_process)
for program in "${TARGET_PROGRAMS[@]}"; do
# 检查程序是否在运行
if pgrep -x "$program" &> /dev/null; then
# 获取程序最后活动时间
last_active=$(get_last_active_time "$program")
if [ -n "$last_active" ] && [ "$last_active" -gt 0 ]; then
inactive_time=$((current_time - last_active))
# 检查程序是否当前活跃(是活跃窗口)
if [ "$active_process" != "$program" ]; then
if [ "$inactive_time" -gt "$INACTIVE_LIMIT" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - 程序 $program 不活跃超过 ${INACTIVE_LIMIT}秒 (实际:${inactive_time}秒),正在终止..."
# 终止程序(使用SIGTERM先,如果不行再用SIGKILL)
pkill -x "$program" 2>/dev/null
sleep 2
# 如果进程仍然存在,强制终止
if pgrep -x "$program" &> /dev/null; then
pkill -9 -x "$program" 2>/dev/null
echo "$(date '+%Y-%m-%d %H:%M:%S') - 强制终止 $program"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - $program 已正常终止"
fi
fi
fi
fi
fi
done
sleep "$CHECK_INTERVAL"
done
安装和使用说明
安装依赖工具
# Debian/Ubuntu sudo apt-get install xdotool wmctrl # CentOS/RHEL sudo yum install xdotool wmctrl # macOS (使用brew) brew install xdotool
保存脚本
# 保存为文件 nano kill_inactive.sh # 添加执行权限 chmod +x kill_inactive.sh # 运行脚本 ./kill_inactive.sh
自定义配置
INACTIVE_LIMIT: 不活跃超时时间(秒)CHECK_INTERVAL: 检查间隔(秒)TARGET_PROGRAMS: 要监控的程序列表
替代方案:Python版本(更可靠)
#!/usr/bin/env python3
import os
import time
import subprocess
import json
from datetime import datetime
# 配置
INACTIVE_LIMIT = 300 # 5分钟
CHECK_INTERVAL = 60 # 1分钟
TARGET_PROGRAMS = ["firefox", "google-chrome", "code"]
def get_active_window_process():
"""获取当前活跃窗口的进程名"""
try:
# 使用xdotool获取活跃窗口PID
result = subprocess.run(
["xdotool", "getactivewindow", "getwindowpid"],
capture_output=True, text=True, timeout=2
)
if result.returncode == 0:
pid = result.stdout.strip()
# 获取进程名
proc_result = subprocess.run(
["ps", "-p", pid, "-o", "comm="],
capture_output=True, text=True, timeout=2
)
if proc_result.returncode == 0:
return proc_result.stdout.strip()
except:
pass
return None
def get_process_last_active(pid):
"""获取进程最后活动时间(文件访问时间)"""
try:
proc_dir = f"/proc/{pid}"
if os.path.exists(proc_dir):
# 使用进程的文件访问时间作为活动指示
stat_info = os.stat(proc_dir)
return stat_info.st_atime
except:
pass
return None
def kill_process(process_name):
"""终止进程"""
try:
# 先尝试正常终止
subprocess.run(["pkill", "-x", process_name], timeout=5)
time.sleep(2)
# 检查是否还在运行,强制终止
check = subprocess.run(
["pgrep", "-x", process_name],
capture_output=True, text=True
)
if check.stdout.strip():
subprocess.run(["pkill", "-9", "-x", process_name], timeout=5)
return "force_killed"
return "killed"
except Exception as e:
return f"error: {e}"
def main():
print(f"启动不活跃程序监控...")
print(f"不活跃阈值:{INACTIVE_LIMIT}秒")
print(f"检查间隔:{CHECK_INTERVAL}秒")
print(f"监控程序:{TARGET_PROGRAMS}")
print("-" * 40)
while True:
try:
current_time = time.time()
active_process = get_active_window_process()
# 获取所有目标程序的PID
for program in TARGET_PROGRAMS:
result = subprocess.run(
["pgrep", "-x", program],
capture_output=True, text=True
)
pids = result.stdout.strip().split('\n') if result.stdout.strip() else []
for pid in pids:
if not pid:
continue
last_active = get_process_last_active(pid)
if last_active:
inactive_time = current_time - last_active
# 检查是否当前活跃
if active_process != program:
if inactive_time > INACTIVE_LIMIT:
print(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - "
f"程序 {program} (PID: {pid}) 不活跃超过 "
f"{INACTIVE_LIMIT}秒 (实际:{int(inactive_time)}秒),终止中...")
status = kill_process(program)
print(f"状态:{status}")
break # 只终止一个实例
time.sleep(CHECK_INTERVAL)
except KeyboardInterrupt:
print("\n监控已停止")
break
except Exception as e:
print(f"错误:{e}")
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
main()
注意事项
- x permission: 需要
xdotool访问X server,可能在Wayland下不工作 - 权限问题: 可能需要root权限来终止某些系统进程
- 准确性: 不活跃检测基于文件访问时间,可能不完全准确
- 资源占用: 监控会占用少量系统资源
自动启动(开机自启)
# 创建systemd服务(Linux) sudo nano /etc/systemd/system/kill_inactive.service [Unit] Description=Kill Inactive Programs Monitor [Service] ExecStart=/path/to/kill_inactive.sh Restart=always User=your_username [Install] WantedBy=default.target # 启用服务 sudo systemctl enable kill_inactive.service sudo systemctl start kill_inactive.service
选择适合你系统的版本,并根据需要调整配置参数。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播