飞牛os控制风扇转速的脚本实现降噪
前言
双十一入了拾光坞G2,性价比其实很高,3盘位完全满足我的需求,还是品牌NAS,官方支持刷机且有3年质保,到手直接刷飞牛,近乎完美。
唯一缺点就是默认40%的风扇有点吵,飞牛系统没有风扇控制的选项,装了CoolerControl但没有风扇驱动,BIOS好像也是阉割过的没有风扇控制功能。找了一圈发现fanctrl可以控制,改写了一个控温脚本,目前感觉不错。
手动控制风扇转速
下载G2 风扇控制转速程序
wget http://down.sgwbox.com/tools/x86/fanctrl /root/fanctrl
chmod +x /root/fanctrl
用法
./fanctrl (0~100)
例如:
./fanctrl 30 表示设置风扇转速为30%
./fanctrl 80 表示设置风扇转速为80%
实测常规设置风扇转速为35%是基本听不到声音的;大于60就开始吵了。
风控脚本并开机自启
原帖的脚本我测试后无法正常工作,所以用豆包写了一个,感觉不错就分享出来,有问题直接发给AI就可以修改。
脚本功能
- 多源温度检测
- 智能风扇控制
- 完整日志记录
- 休眠保护
风扇温控脚本(fan_control.sh)
#!/bin/bash
set -eo pipefail
# ================================== 配置项 ==================================
STATE_FILE="/var/run/fan_control.state" # 状态保存文件
LOG_FILE="/var/log/fan_control.log" # 日志文件
FAN_CTRL="/root/fanctrl" # 风扇控制程序路径
CHECK_INTERVAL=60 # 检测间隔(秒)
MAX_CPU_TEMP=80 # CPU温度阈值(℃)
MAX_HDD_TEMP=50 # 硬盘温度阈值(℃)
SAFE_FAN_SPEED=30 # 安全温度下的风扇转速(%)
INCREASE_STEP=10 # 超温时每次增加的转速(%)
MAX_FAN_SPEED=100 # 最大风扇转速(%)
# =============================================================================
# 初始化日志和状态文件
init_files() {
# 创建日志文件(确保权限)
if [ ! -f "$LOG_FILE" ]; then
touch "$LOG_FILE"
chmod 644 "$LOG_FILE"
fi
# 初始化状态文件
if [ ! -f "$STATE_FILE" ]; then
echo "current_speed=$SAFE_FAN_SPEED" > "$STATE_FILE"
echo "last_action=initialized" >> "$STATE_FILE"
echo "last_temp_check=$(date +%s)" >> "$STATE_FILE"
# 初始设置风扇转速
if [ -x "$FAN_CTRL" ]; then
"$FAN_CTRL" "$SAFE_FAN_SPEED" >/dev/null 2>&1
log "初始化风扇转速为 $SAFE_FAN_SPEED%"
else
log "错误:未找到风扇控制程序 $FAN_CTRL,请先安装"
exit 1
fi
fi
}
# 日志记录函数
log() {
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
echo "[$timestamp] $1" >> "$LOG_FILE"
}
# 读取当前状态
read_state() {
source "$STATE_FILE" 2>/dev/null || {
log "状态文件损坏,重新初始化"
init_files
source "$STATE_FILE"
}
}
# 更新状态文件
update_state() {
local speed=$1
local action=$2
echo "current_speed=$speed" > "$STATE_FILE"
echo "last_action=$action" >> "$STATE_FILE"
echo "last_temp_check=$(date +%s)" >> "$STATE_FILE"
}
# 获取CPU温度(兼容多种系统)
get_cpu_temp() {
# 优先尝试x86_pkg_temp
if [ -f "/sys/class/thermal/thermal_zone0/temp" ]; then
local temp=$(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null)
if [ -n "$temp" ] && [ "$temp" -gt 0 ]; then
echo $((temp / 1000))
return 0
fi
fi
# 尝试coretemp(多核心取最高)
local core_temp=$(sensors | grep -i 'core' | grep -oP '\d+°C' | grep -oP '\d+' | sort -nr | head -1)
if [ -n "$core_temp" ]; then
echo "$core_temp"
return 0
fi
# 尝试proc文件系统
local proc_temp=$(cat /proc/cpuinfo | grep -i 'temperature' | grep -oP '\d+' | head -1)
if [ -n "$proc_temp" ]; then
echo "$proc_temp"
return 0
fi
# 所有方法失败
log "警告:无法获取CPU温度"
return 1
}
# 获取硬盘温度(兼容多种检测方式)
get_hdd_temp() {
local hdd_devices=$(lsblk -o NAME,TYPE | grep -i 'disk' | grep -v 'loop' | awk '{print $1}')
local max_hdd_temp=0
for dev in $hdd_devices; do
local device="/dev/$dev"
# 检查硬盘是否休眠,避免唤醒
if hdparm -C "$device" 2>/dev/null | grep -qi 'standby\|sleeping'; then
continue
fi
# 尝试smartctl
local temp=$(smartctl -A "$device" 2>/dev/null | grep -i 'temperature' | awk '{print $10}' | head -1)
if [ -z "$temp" ] || [ "$temp" -eq 0 ]; then
# 尝试hddtemp
temp=$(hddtemp -n "$device" 2>/dev/null)
fi
# 记录最高温度
if [ -n "$temp" ] && [ "$temp" -gt "$max_hdd_temp" ]; then
max_hdd_temp=$temp
fi
done
if [ "$max_hdd_temp" -gt 0 ]; then
echo "$max_hdd_temp"
return 0
else
log "警告:无法获取硬盘温度"
return 1
fi
}
# 控制风扇转速
control_fan() {
local target_speed=$1
# 检查转速范围
if [ "$target_speed" -lt 0 ] || [ "$target_speed" -gt 100 ]; then
log "无效转速 $target_speed%,限制在0-100之间"
target_speed=$(( target_speed < 0 ? 0 : 100 ))
fi
# 执行转速设置
if [ -x "$FAN_CTRL" ]; then
"$FAN_CTRL" "$target_speed" >/dev/null 2>&1
if [ $? -eq 0 ]; then
log "风扇转速已设置为 $target_speed%"
return 0
else
log "错误:设置风扇转速 $target_speed% 失败"
return 1
fi
else
log "错误:风扇控制程序 $FAN_CTRL 不存在或不可执行"
return 1
fi
}
# 温度监控主逻辑
monitor_temps() {
read_state
local current_speed=$current_speed
# 获取温度
local cpu_temp=$(get_cpu_temp)
local hdd_temp=$(get_hdd_temp)
# 检查温度是否有效
local temp_valid=1
if [ -z "$cpu_temp" ] && [ -z "$hdd_temp" ]; then
log "无法获取任何温度数据,跳过本次调整"
temp_valid=0
fi
if [ $temp_valid -eq 1 ]; then
# 决定是否需要调整转速
local need_increase=0
if [ -n "$cpu_temp" ] && [ "$cpu_temp" -ge "$MAX_CPU_TEMP" ]; then
need_increase=1
fi
if [ -n "$hdd_temp" ] && [ "$hdd_temp" -ge "$MAX_HDD_TEMP" ]; then
need_increase=1
fi
# 计算目标转速
local target_speed=$current_speed
if [ $need_increase -eq 1 ]; then
# 超温时逐步增加转速
target_speed=$((current_speed + INCREASE_STEP))
if [ "$target_speed" -gt "$MAX_FAN_SPEED" ]; then
target_speed=$MAX_FAN_SPEED
fi
else
# 温度正常时恢复到安全转速
if [ "$current_speed" -ne "$SAFE_FAN_SPEED" ]; then
target_speed=$SAFE_FAN_SPEED
fi
fi
# 执行调整(只有转速变化时才操作)
if [ "$target_speed" -ne "$current_speed" ]; then
if control_fan "$target_speed"; then
update_state "$target_speed" "温度触发调整 (CPU: ${cpu_temp:-未知}°C, HDD: ${hdd_temp:-未知}°C)"
fi
else
log "CPU温度: ${cpu_temp:-未知}°C, 硬盘温度: ${hdd_temp:-未知}°C, 风扇转速: $current_speed% (无需调整)"
fi
fi
}
# 显示状态
show_status() {
read_state
local cpu_temp=$(get_cpu_temp || echo "未知")
local hdd_temp=$(get_hdd_temp || echo "未知")
echo "===== 风扇温控状态 ====="
echo "当前风扇转速: $current_speed%"
echo "CPU温度阈值: $MAX_CPU_TEMP°C"
echo "硬盘温度阈值: $MAX_HDD_TEMP°C"
echo ""
echo "CPU当前温度: $cpu_temp°C"
echo "硬盘当前温度: $hdd_temp°C"
echo ""
echo "最后操作: $last_action"
echo "========================"
}
# 主程序入口
main() {
# 检查是否以root运行
if [ "$(id -u)" -ne 0 ]; then
echo "错误:请以root权限运行(sudo)"
exit 1
fi
# 检查依赖
local dependencies=("hdparm" "hddtemp" "sensors")
for dep in "${dependencies[@]}"; do
if ! command -v "$dep" &>/dev/null; then
echo "错误:缺少依赖 $dep,请先安装"
exit 1
fi
done
init_files
case "$1" in
--service)
log "启动风扇温控服务(间隔 $CHECK_INTERVAL 秒)"
while true; do
monitor_temps
sleep $CHECK_INTERVAL
done
;;
--status)
show_status
;;
--log)
tail -f "$LOG_FILE"
;;
--restart)
log "手动重启服务"
control_fan "$SAFE_FAN_SPEED"
update_state "$SAFE_FAN_SPEED" "手动重启"
echo "服务已重启,风扇转速重置为 $SAFE_FAN_SPEED%"
;;
*)
echo "用法:"
echo " $0 --service 启动温控服务(守护进程)"
echo " $0 --status 查看当前状态"
echo " $0 --log 查看实时日志"
echo " $0 --restart 重启服务并重置风扇转速"
exit 1
;;
esac
}
main "$@"
脚本改进说明
- 增强兼容性:优化了 CPU / 硬盘温度检测逻辑,适配更多 Linux 发行版(。
- 完善错误处理:增加了文件权限检查、依赖检测、程序存在性验证,避免静默失败。
- 状态可视化:
--status命令更清晰地展示当前状态,方便排查问题。 - 可靠性提升:增加了
--restart命令,可手动重置状态,解决可能的状态文件损坏问题。 - 日志优化:更详细的日志记录,便于追踪脚本运行情况。
使用步骤
-
安装基础依赖(确保先执行):
apt update && apt install -y hdparm hddtemp smartmontools lm-sensors sensors-detect # 按提示完成传感器检测(一路按回车即可) -
下载风扇控制程序:
wget http://down.sgwbox.com/tools/x86/fanctrl -O /root/fanctrl && chmod +x /root/fanctrl -
创建新脚本:
# 复制上面的脚本内容到文件中 nano /usr/local/bin/fan_control.sh # 保存后设置权限 chmod +x /usr/local/bin/fan_control.sh -
测试脚本:
# 查看状态(验证是否正常运行) /usr/local/bin/fan_control.sh --status -
设置系统服务(开机自启):
# 创建服务文件 tee /etc/systemd/system/fan-control.service <<EOF [Unit] Description=Fan Control Service After=multi-user.target [Service] Type=simple ExecStart=/usr/local/bin/fan_control.sh --service Restart=always RestartSec=60 User=root WorkingDirectory=/root [Install] WantedBy=multi-user.target EOF # 启动并设置自启 systemctl daemon-reload systemctl enable --now fan-control -
检查服务状态:
systemctl status fan-control # 查看服务是否运行 tail -f /var/log/fan_control.log # 查看实时日志

如果运行仍有问题,可通过日志文件 /var/log/fan_control.log 查看具体错误信息,或执行 systemctl status fan-control 检查服务状态,以便进一步排查。

安装依赖
-
安装
hddtemp依赖,按以下步骤安装即可解决,部分系统需额外处理兼容性问题。第一步:优先常规安装
-
执行标准安装命令(适用于 Debian/Ubuntu/PVE 等基于 Debian 的系统):
apt update && apt install -y hddtemp -
安装完成后,重新运行脚本测试:
/usr/local/bin/fan_control.sh --status第二步:若安装失败(无软件包)
-
先确认软件源是否包含
hddtemp,执行搜索:apt search hddtemp -
若搜索结果为空,手动下载安装(以 Debian 12/ Ubuntu 22.04 为例):
# 下载适配 x86_64 架构的 deb 包 wget http://ftp.debian.org/debian/pool/main/h/hddtemp/hddtemp_0.3-beta15-54_amd64.deb # 安装下载的包 dpkg -i hddtemp_0.3-beta15-54_amd64.deb # 修复依赖缺失(若有报错) apt -f install -y第三步:安装后验证
command -v hddtemp # 输出 /usr/sbin/hddtemp 即成功
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 无辣的学习笔记
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果