背景
日常开发 Java 的过程中, 需要连接 Mysql, Redis, Nacos, Sentinel 等组件,并且我经常需要在 Linux,Windows 和 Macos 之间进行切换,切换之后环境里面的数据又不一致,导致切换之后总是需要进行数据迁移,因此想搞一个 24 小时开机的 Linux 服务器。
刚好手上有一台大学时期的笔记本,工作之后就一直在角落里面吃灰,拿来当 24 小时开机的低功耗 Linux 服务器刚刚好。操作系统选择的是 Debian 12.8。
温馨提示:文章不介绍怎么装操作系统,只介绍装机之后,遇到的一些问题,以及如何解决这些问题。
笔记本合上之后自动挂起
成功安装完操作系统后,发现只要把笔记本合上,电脑就自动挂起了,导致 SSH 连接不上,不想电脑自动挂起需要执行如下的操作。
- 修改
/etc/systemd/logind.conf配置文件
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore
- 重启
systemctl-logind服务
systemctl restart systemd-logind.service
自动亮屏和熄屏
系统如果正常运行,不挂起,笔记本的屏幕会一直亮着,对于 24 小时的服务器,能省点电费就省点吧。实现原理:通过 acpid 监听合盖和开盖的事件,然后自动执行熄屏和亮屏的命令。
- 安装
acpid
apt install acpid
- 开机自启动
acpid
systemctl enable acpid.service
- 查看合盖和开盖事件名称
在终端中运行 acpi_listen 命令,然后手动的合盖和开盖,查看终端中输出的事件名称,下面是我笔记本上输出的事件名称
button/lid LID close
button/lid LID open
- 创建
apci事件配置文件
在 /etc/acpi/events/ 文件夹中新增一个文件用来监听合盖和开盖的事件,例如:创建一个名为 lid-switch 的文件:
vim /etc/acpi/events/lid-switch
在文件中添加如下的内容:
event=button/lid.*
action=/etc/acpi/lid-switch.sh %e
- event 参数表示监听所有以
button/lid开头的事件 - action 参数表示系统触发监听事件后,执行
/etc/acpi/lid-switch.sh脚本,并将完整的事件信息 (%e) 作为参数传递给脚本
- 创建
lid-switch.sh脚本
创建 /etc/acpi/lid-switch.sh 脚本:
vim /etc/acpi/lid-switch.sh
脚本内容如下:
#!/bin/bash
logger "ACPI lid event triggered: $@"
# `/sys/class/backlight/` 目录在 Linux 系统中用于管理和控制显示器的背光亮度
# 该目录包含了系统中可用的背光设备的信息和接口,通常用于调整屏幕亮度
# 找到笔记本中控制背光的设备
BACKLIGHT_DIR=$(find /sys/class/backlight/ -maxdepth 1 -type l | head -n 1)
if [ -z "$BACKLIGHT_DIR" ]; then
logger "Error: device not found initially."
else
logger "Found backlight device: $BACKLIGHT_DIR"
fi
# 找出存储笔记本开盖合盖状态的文件
LID_STATE_FILE=$(find /proc/acpi/button/lid/ -name state | head -n 1)
# CURRENT_STATE=$(cat /proc/acpi/button/lid/LID0/state | awk '{print $2}')
# 查看笔记本当前的状态
CURRENT_STATE=$(cat $LID_STATE_FILE | awk '{print $2}')
logger "CURRENT_STATE: $CURRENT_STATE"
if grep -q "closed" <<< "$CURRENT_STATE"; then
logger "Lid closed. Attempting to turn off screen."
if [ -d "$BACKLIGHT_DIR" ]; then
# --- Turn off backlight ---
logger "Attempting command: echo 0 | tee $BACKLIGHT_DIR/brightness"
# 关闭屏幕
echo 0 | tee "$BACKLIGHT_DIR/brightness"
EXIT_STATUS=$?
logger "tee command finished. Exit status: $EXIT_STATUS"
if [ $EXIT_STATUS -ne 0 ]; then
logger "ERROR: Failed to write 0 to brightness file!"
else
# Optional: Read back value to confirm
CURRENT_BRIGHTNESS=$(cat "$BACKLIGHT_DIR/brightness")
logger "Brightness value after write: $CURRENT_BRIGHTNESS"
fi
else
logger "Error: Backlight device was not found when trying to turn off."
fi
elif grep -q "open" <<< "$CURRENT_STATE"; then
logger "Lid opened. Attempting to turn on screen."
if [ -d "$BACKLIGHT_DIR" ]; then
# --- Restore brightness ---
MAX_BRIGHTNESS=$(cat "$BACKLIGHT_DIR/max_brightness")
logger "Attempting command: echo $MAX_BRIGHTNESS | tee $BACKLIGHT_DIR/brightness"
# 打开屏幕
echo "$MAX_BRIGHTNESS" | tee "$BACKLIGHT_DIR/brightness"
EXIT_STATUS=$?
logger "tee command finished. Exit status: $EXIT_STATUS"
if [ $EXIT_STATUS -ne 0 ]; then
logger "ERROR: Failed to write $MAX_BRIGHTNESS to brightness file!"
else
# Optional: Read back value to confirm
CURRENT_BRIGHTNESS=$(cat "$BACKLIGHT_DIR/brightness")
logger "Brightness value after restore: $CURRENT_BRIGHTNESS"
fi
else
logger "Error: Backlight device was not found when trying to turn on."
fi
else
logger "Unknown lid state: $CURRENT_STATE"
fi
exit 0
问题排查
可以通过下面的指令排查各个阶段的问题
# 1. 查看合盖和开盖的事件
acpi_listen
# 2. 查看 acpid 的日志
journalctl -u acpid.service -f
# 3. 查看 `/etc/acpi/lid-switch.sh` 脚本中 `logger` 命令产生的日志
journalctl -f
# 4. 查看最大亮度
cat /sys/class/backlight/intel_backlight/max_brightness
# 5. 关闭屏幕
echo 0 | sudo tee /sys/class/backlight/intel_backlight/brightness
# 6. 打开屏幕
echo $(cat /sys/class/backlight/intel_backlight/max_brightness) | sudo tee /sys/class/backlight/intel_backlight/brightness