Linux
树莓派3B 采用Samba + Cockpit搭建NAS
Linux 修改开机启动 boot splash logos
Linux 下将 .po 文件编译成 .mo 文件
Python 使用 gettext 模块实现国际化
XFCE 桌面优化配置
香橙派3B 使用 WiringOP 读取 MPU6050
香橙派4 LTS 安装 WiringPi
Linux 图形界面切换到 FB 界面
校表仪 tg-timer 算法笔记
Linux 安装 EtherCat Igh
EetherCat Igh 常用指令
树莓派镜像 DIY 制作
树莓派5B 安装64位实时系统 preempt RT 补丁
linux 的 lightdm 桌面管理器下隐藏光标(鼠标)
Linux 上使用 MPD (Music Player Daemon)
Linux 自动化交互式命令行工具 —— expect
Linux GTK 界面开发
Debian系统中修改主机名
使用Python + GTK3.0 开发嵌入式GUI
Raspberry Pi 5修改系统内存分页大小解决安装esp-matter 出现的<jemalloc>: Unsupported systeom page size 错误
树莓派 linux 安装和使用clash 做VPN
树莓派自动挂载硬盘
非控制台或ssh登录用户尝试启动Xorg图形服务器
XFCE4 电源管理器配置管理
Linux PulseAudio 声卡配置和检测
IBUS修改输入法和设置切换快捷键
在 Moode Audio 中实现开机自动启动 `startx`
crontab 任务
树莓派外设耗电检测
linux 终端自动登录
linux创建新用户
linux service通过xinit启动GTK应用程序
Linux 非桌面的图形环境安装和配置
香橙派3b板载音频输出没有声音调试
使用 udev 规则修改权限实现屏幕亮度调节
Linux udev 介绍
鲁班猫4 ubuntu22.04 屏幕背光 udev 自动配置化
ubuntu22.04 动态壁纸配置
使用 udisksctl 的可靠 USB 自动挂载方案(基于 systemd-run)
通过udev规则U盘自动挂载
OpenWRT 磊科N60pro路由器刷机
本文档使用 MrDoc 发布
-
+
首页
Linux 非桌面的图形环境安装和配置
图形化安装脚本 ```bash SCRIPTPATH=$(dirname -- "$(readlink -f -- "$0")") # 终端模拟器 xterm XSERVER="xinit xinput x11-xserver-utils xserver-xorg-input-evdev xserver-xorg-input-libinput xserver-xorg-legacy xserver-xorg-video-fbdev xterm" CAGE="cage seatd xwayland" PYGOBJECT="libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0" MISC="librsvg2-common libopenjp2-7 libdbus-glib-1-dev autoconf python3-venv" OPTIONAL="fonts-nanum fonts-ipafont fonts-wqy-zenhei libmpv-dev alsa-utils pulseaudio" Red='\033[0;31m' Green='\033[0;32m' Cyan='\033[0;36m' Normal='\033[0m' echo_text () { printf "${Normal}$1${Cyan}\n" } echo_error () { printf "${Red}$1${Normal}\n" } echo_ok () { printf "${Green}$1${Normal}\n" } install_graphical_backend() { while true; do if [ -z "$BACKEND" ]; then echo_text "" echo_text "Choose graphical backend" echo_ok "Default is Xserver" echo_text "Wayland is EXPERIMENTAL needs kms/drm drivers doesn't support DPMS and may need autologin" echo_text "" echo "Press enter for default (Xserver)" read -r -e -p "Backend Xserver or Wayland (cage)? [X/w]" BACKEND if [[ "$BACKEND" =~ ^[wW]$ ]]; then echo_text "Installing Wayland Cage Kiosk" if sudo apt install -y $CAGE; then echo_ok "Installed Cage" BACKEND="W" break else echo_error "Installation of Cage dependencies failed ($CAGE)" exit 1 fi else echo_text "Installing Xserver" if sudo apt install -y $XSERVER; then echo_ok "Installed X" update_x11 BACKEND="X" break else echo_error "Installation of X-server dependencies failed ($XSERVER)" exit 1 fi fi fi done } # 安装依赖包 install_packages() { echo_text "Update package data" sudo apt update echo_text "Checking for broken packages..." if dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | grep -E "^.[^nci]"; then echo_text "Detected broken packages. Attempting to fix" sudo apt -f install if dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' | grep -E "^.[^nci]"; then echo_error "Unable to fix broken packages. These must be fixed before KlipperScreen can be installed" exit 1 fi else echo_ok "No broken packages" fi echo_text "Installing KlipperScreen dependencies" sudo apt install -y $OPTIONAL echo "$_" if sudo apt install -y $PYGOBJECT; then echo_ok "Installed PyGobject dependencies" else echo_error "Installation of PyGobject dependencies failed ($PYGOBJECT)" exit 1 fi if sudo apt install -y $MISC; then echo_ok "Installed Misc packages" else echo_error "Installation of Misc packages failed ($MISC)" exit 1 fi } install_systemd_service() { # echo_text "Installing KlipperScreen unit file" # echo 配合 tee 实现对需要 root 权限文件的写入 # SERVICE=$(cat "$SCRIPTPATH"/KlipperScreen.service) # 进行全局变量替换 # // 表示全局替换(所有匹配的旧字符串都会被替换)。 # SERVICE=${SERVICE//KS_USER/$USER} # SERVICE=${SERVICE//KS_ENV/$KSENV} # SERVICE=${SERVICE//KS_DIR/$KSPATH} # SERVICE=${SERVICE//KS_BACKEND/$BACKEND} # echo "$SERVICE" | sudo tee /etc/systemd/system/KlipperScreen.service > /dev/null # sudo systemctl unmask KlipperScreen.service # sudo systemctl daemon-reload # sudo systemctl enable KlipperScreen sudo systemctl set-default multi-user.target sudo adduser "$USER" tty } # 为 KlipperScreen 配置 PolicyKit (polkit) 权限规则,允许特定用户或用户组执行网络管理和电源操作(如关机、重启)而无需 root 密码 create_policy() { POLKIT_DIR="/etc/polkit-1/rules.d" POLKIT_USR_DIR="/usr/share/polkit-1/rules.d" echo_text "Installing KlipperScreen PolicyKit Rules" sudo groupadd -f klipperscreen sudo groupadd -f network sudo adduser "$USER" netdev sudo adduser "$USER" network if [ ! -x "$(command -v pkaction)" ]; then echo "PolicyKit not installed" return fi POLKIT_VERSION="$( pkaction --version | grep -Po "(\d+\.?\d*)" )" echo_text "PolicyKit Version ${POLKIT_VERSION} Detected" if [ "$POLKIT_VERSION" = "0.105" ]; then # install legacy pkla create_policy_legacy return fi RULE_FILE="" if [ -d $POLKIT_USR_DIR ]; then RULE_FILE="${POLKIT_USR_DIR}/KlipperScreen.rules" elif [ -d $POLKIT_DIR ]; then RULE_FILE="${POLKIT_DIR}/KlipperScreen.rules" else echo "PolicyKit rules folder not detected" exit 1 fi echo_text "Installing PolicyKit Rules to ${RULE_FILE}..." sudo rm ${RULE_FILE} KS_GID=$( getent group klipperscreen | awk -F: '{printf "%d", $3}' ) sudo tee ${RULE_FILE} > /dev/null << EOF polkit.addRule(function(action, subject) { if (action.id.indexOf("org.freedesktop.NetworkManager.") == 0 && subject.isInGroup("network")) { return polkit.Result.YES; } }); polkit.addRule(function(action, subject) { if ((action.id == "org.freedesktop.login1.power-off" || action.id == "org.freedesktop.login1.power-off-multiple-sessions" || action.id == "org.freedesktop.login1.reboot" || action.id == "org.freedesktop.login1.reboot-multiple-sessions" || action.id == "org.freedesktop.login1.halt" || action.id == "org.freedesktop.login1.halt-multiple-sessions" || action.id.startsWith("org.freedesktop.NetworkManager.")) && subject.user == "$USER") { return polkit.Result.YES; } } }); EOF } create_policy_legacy() { RULE_FILE="/etc/polkit-1/localauthority/50-local.d/20-klipperscreen.pkla" sudo tee ${RULE_FILE} > /dev/null << EOF [KlipperScreen] Identity=unix-user:$USER Action=org.freedesktop.login1.power-off; org.freedesktop.login1.power-off-multiple-sessions; org.freedesktop.login1.reboot; org.freedesktop.login1.reboot-multiple-sessions; org.freedesktop.login1.halt; org.freedesktop.login1.halt-multiple-sessions; org.freedesktop.NetworkManager.* ResultAny=yes EOF } # 允许通过终端启动x display update_x11() { sudo tee /etc/X11/Xwrapper.config > /dev/null << EOF allowed_users=anybody needs_root_rights=yes EOF } # 网络配置 install_network_manager() { if [ -z "$NETWORK" ]; then echo "Press enter for default (Yes)" read -r -e -p "Install NetworkManager for the network panel [Y/n]" NETWORK if [[ $NETWORK =~ ^[nN]$ ]]; then echo_error "Not installing NetworkManager for the network panel" else echo_ok "Installing NetworkManager for the network panel" echo_text "" echo_text "If you were not using NetworkManager" echo_text "You will need to reconnect to the network using KlipperScreen or nmtui or nmcli" sudo apt install network-manager sudo mkdir -p /etc/NetworkManager/conf.d sudo tee /etc/NetworkManager/conf.d/any-user.conf > /dev/null << EOF [main] auth-polkit=false EOF sudo systemctl -q disable dhcpcd 2> /dev/null sudo systemctl -q stop dhcpcd 2> /dev/null sudo systemctl enable NetworkManager sudo systemctl -q --no-block start NetworkManager sync systemctl reboot fi fi } #################################################### # Script start if [ "$EUID" == 0 ] then echo_error "Please do not run this script as root" exit 1 fi if [ -z "$SERVICE" ]; then echo_text "Install standalone?" echo_text "It will create a service, enable boot to console and install the graphical dependencies." echo_text "" echo_text "Say no to install as a regular desktop app that will not start automatically" echo_text "" echo "Press enter for default (Yes)" read -r -e -p "[Y/n]" SERVICE if [[ $SERVICE =~ ^[nN]$ ]]; then echo_text "Not installing the service" echo_text "The graphical backend will NOT be installed" else install_graphical_backend install_systemd_service if [ -z "$START" ]; then START=1 fi fi fi install_packages create_policy # 配置 PolicyKit (polkit) 权限规则 install_network_manager if [ -z "$START" ] || [ "$START" -eq 0 ]; then echo_ok "Env was installed" fi ``` 不使用system 进行程序的启动管理,直接配置~/.xinitrc 和 ~/.bash_profile文件进行程序的开机自启动 ```~/.xinitrc #!/usr/bin/bash # 安装chromium-browser : sudo apt install chromium-browser # Turn off display power management xset -dpms # Screensaver timeout in secs or 'off' for no timeout # xset s 600 xset s off # Capture native screen size fgrep "#dtoverlay=vc4-kms-v3d" /boot/firmware/config.txt if [ $? -ne 0 ]; then # SCREEN_RES=$(kmsprint | awk '$1 == "FB" {print $3}' | awk -F"x" '{print $1","$2}') SCREEN_RES=$(kmsprint | awk '$1 == "FB" {print $3}' | awk -F"x" '{print $2","$1}') else # SCREEN_RES=$(fbset -s | awk '$1 == "geometry" {print $2","$3}') SCREEN_RES=$(fbset -s | awk '$1 == "geometry" {print $3","$2}') fi echo "SCREEN_RES:$SCREEN_RES" /usr/bin/chromium-browser --app="http://localhost:8080/" \ --window-size="$SCREEN_RES" \ --window-position="0,0" \ --enable-features="OverlayScrollbar" \ --no-first-run \ --disable-infobars \ --disable-session-crashed-bubble \ --kiosk ``` ``` ~/.xinitrc 等待音频服务器启动 #!/bin/sh # 等待 PulseAudio 和 ALSA 就绪 while ! pgrep -x "pulseaudio" >/dev/null; do sleep 1 done while ! aplay -l | grep -q "card"; do sleep 1 done xset s off # 关闭屏幕保护 xset -dpms # 关闭 DPMS(Display Power Management Signaling) xset s noblank # 禁止屏幕变黑 xsetroot -cursor /etc/emptycursor /etc/emptycursor # 空白光标 # 执行应用 exec app ``` ``` /etc/emptycursor #define nn1_width 16 #define nn1_height 16 static unsigned char nn1_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ``` ```~/.bash_profile if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then # -nocursor 没有光标启动 exec startx -- :0 -nocursor fi ``` 临时手动设置显示器环境,便于当前终端执行 xset 等屏幕相关指令 ```bash export DISPLAY=:0 ```
qingkai
2025年5月15日 21:31
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码