Ubuntu 虚拟显示器自动控制服务设置(有无显示器的切换)

问题描述:ubuntu桌面版在做服务器情况不带显示器的情况下与向日葵等远程办公软件不兼容,引入虚拟显示器方式,但是后续如果要使用物理显示器的话又需要将配置的虚拟显示器文件conf删除(否则物理显示器黑屏或卡死),操作繁琐。本文旨在做一套自动检测,切换配置的脚本教程,解决部分特定场景的需要。

脚本设置

1. 修改脚本(服务将以 root 权限运行)

#!/bin/bash

# Ubuntu 虚拟显示器自动控制脚本
# 功能:自动检测显示器状态并相应启用/禁用虚拟显示器

CONFIG_PATH="/usr/share/X11/xorg.conf.d/xorg.conf"
CONFIG_CONTENT='
Section "Monitor"
    Identifier "Monitor0"
    HorizSync 28.0-80.0
    VertRefresh 48.0-75.0
    Modeline "1920x1080_60.00" 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -HSync +Vsync
EndSection

Section "Device"
    Identifier "Card0"
    Driver "dummy"
    VideoRam 256000
EndSection

Section "Screen"
    DefaultDepth 24
    Identifier "Screen0"
    Device "Card0"
    Monitor "Monitor0"
    SubSection "Display"
        Depth 24
        Modes "1920x1080_60.00"
    EndSubSection
EndSection
'

# 检测是否有真实显示器连接
has_real_display() {
    # 尝试使用xrandr检测连接的显示器
    if command -v xrandr >/dev/null 2>&1; then
        # 检查是否有已连接的显示器(排除虚拟显示器)
        if xrandr --listmonitors 2>/dev/null | grep -v "dummy" | grep -q " connected"; then
            return 0 # 有真实显示器
        fi
    fi
    
    # 备用检测方法:检查DRM设备
    if [ -d "/sys/class/drm" ]; then
        for card in /sys/class/drm/card*-*; do
            if [ -e "$card/status" ] && [ "$(cat "$card/status" 2>/dev/null)" = "connected" ]; then
                if ! echo "$card" | grep -q "dummy"; then
                    return 0 # 有真实显示器
                fi
            fi
        done
    fi
    
    return 1 # 没有真实显示器
}

# 创建虚拟显示器配置
create_virtual_display() {
    echo "正在创建虚拟显示器配置..."
    mkdir -p /usr/share/X11/xorg.conf.d/
    echo "$CONFIG_CONTENT" | tee "$CONFIG_PATH" > /dev/null
    
    if [ -f "$CONFIG_PATH" ]; then
        echo "✓ 配置文件已创建: $CONFIG_PATH"
        restart_display_manager
        return 0
    else
        echo "✗ 配置文件创建失败!"
        return 1
    fi
}

# 删除虚拟显示器配置
remove_virtual_display() {
    echo "正在禁用虚拟显示器配置..."
    rm -f "$CONFIG_PATH"
    
    if [ ! -f "$CONFIG_PATH" ]; then
        echo "✓ 配置文件已禁用"
        restart_display_manager
        return 0
    else
        echo "✗ 配置文件禁用失败!"
        return 1
    fi
}

# 重启显示管理器
restart_display_manager() {
    echo "⏳ 正在重启显示服务..."
    
    # 自动检测当前显示管理器
    if systemctl is-active --quiet gdm3; then
        systemctl restart gdm3
        echo "✓ 已重启 gdm3 服务"
    elif systemctl is-active --quiet lightdm; then
        systemctl restart lightdm
        echo "✓ 已重启 lightdm 服务"
    else
        systemctl restart display-manager
        echo "✓ 已重启 display-manager 服务"
    fi
}

# 自动检测并调整显示器配置
auto_adjust_display() {
    if has_real_display; then
        # 有真实显示器,应禁用虚拟显示器
        if [ -f "$CONFIG_PATH" ]; then
            echo "检测到真实显示器,禁用虚拟显示器..."
            remove_virtual_display
        else
            echo "检测到真实显示器,无需调整"
        fi
    else
        # 无真实显示器,应启用虚拟显示器
        if [ ! -f "$CONFIG_PATH" ]; then
            echo "未检测到真实显示器,启用虚拟显示器..."
            create_virtual_display
        else
            echo "未检测到真实显示器,无需调整"
        fi
    fi
}

# 主函数 - 直接启动自动监听模式
main() {
    echo "启动 Ubuntu 虚拟显示器自动控制脚本"
    
    # 初始检测一次
    auto_adjust_display
    
    # 然后每10秒检测一次
    while true; do
        sleep 10
        auto_adjust_display
    done
}

# 运行主函数
main

2. 保存脚本并设置权限

sudo nano /usr/local/bin/virtual-display-manager.sh
# 粘贴上面的脚本内容
sudo chmod +x /usr/local/bin/virtual-display-manager.sh

系统服务配置

3. 创建系统服务文件

sudo nano /etc/systemd/system/virtual-display-manager.service

添加以下内容:

[Unit]
Description=Virtual Display Manager
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/local/bin/virtual-display-manager.sh
Restart=always
RestartSec=10
User=root

[Install]
WantedBy=multi-user.target

4. 启用并启动服务

sudo systemctl daemon-reload
sudo systemctl enable virtual-display-manager.service
sudo systemctl start virtual-display-manager.service

重启服务指令:

sudo systemctl restart virtual-display-manager.service

5. 检查服务状态

sudo systemctl status virtual-display-manager.service

服务管理命令

启动服务

sudo systemctl start virtual-display-manager.service

停止服务

sudo systemctl stop virtual-display-manager.service

重启服务

sudo systemctl restart virtual-display-manager.service

禁用开机自启动

sudo systemctl disable virtual-display-manager.service

查看服务日志

sudo journalctl -u virtual-display-manager.service -f

功能说明

这样设置后,脚本将在系统启动时自动运行,并在后台持续监控显示器状态,根据需要启用或禁用虚拟显示器。服务会在意外停止时自动重启(每10秒检查一次),确保始终运行。

注意:切换虚拟显示器配置时会重启显示管理器服务,这将终止当前图形会话和所有运行的图形应用程序。以下是详细说明:

类别

会被终止 (❌)

不会终止 (✅)

应用程序

所有带有图形界面的程序(浏览器、IDE、办公软件)

无图形界面的命令行工具(如 curlwget

终端/Shell

所有图形终端模拟器(GNOME Terminal, Konsole)

文本控制台(tty1-6)中的 Shell

进程类型

在图形终端中运行的前台进程

使用 tmux/screen/nohup 运行的进程

系统服务

所有由 systemd 管理的服务(nginx, docker, sshd)

用户界面

整个桌面环境(GNOME, KDE Plasma, XFCE)

因此,在执行此脚本之前(插入或者拔出物理显示器时),务必要保存所有图形应用程序中的重要工作。 对于需要长时间运行的任务,强烈建议在 tmux 或 screen 会话中启动它们,这样即使图形界面重启,任务也会在后台继续运行,之后可以重新连接恢复。

### 如何在Ubuntu中配置和使用虚拟显示器 #### 安装必要的软件包 为了使虚拟显示器能够正常工作,需要安装特定的X服务器组件。这可以通过以下命令完成: ```bash sudo apt update sudo apt install xserver-xorg-core-hwe-18.04 sudo apt install xserver-xorg-video-dummy-hwe-18.04 --fix-missing ``` 这些命令会更新系统的软件列表并安装所需的驱动程序和支持文件[^4]。 #### 创建XOrg配置文件 创建一个新的XOrg配置文件来定义虚拟屏幕参数非常重要。可以按照如下方式操作: ```bash sudo nano /usr/share/X11/xorg.conf.d/99-fbdev.conf ``` 在这个新创建的`99-fbdev.conf`文件内输入下面的内容以指定分辨率和其他显示属性: ```plaintext Section "Device" Identifier "Configured Video Device" Driver "dummy" EndSection Section "Monitor" Identifier "Configured Monitor" HorizSync 31.5 - 48.5 VertRefresh 50.0 - 70.0 EndSection Section "Screen" Identifier "Default Screen" Monitor "Configured Monitor" Device "Configured Video Device" DefaultDepth 24 SubSection "Display" Depth 24 Modes "1920x1080" EndSubSection EndSection ``` 此配置指定了一个分辨率为1920x1080像素的虚拟显示屏设置[^2]。 #### 重启图形界面服务 保存更改后的配置文件之后,需重新启动计算机或仅重载显示管理器以便应用新的设置: ```bash sudo systemctl restart gdm3 # 或者对于某些系统可能是lightdm而不是gdm3 sudo systemctl restart lightdm ``` 此时应该已经成功设置虚拟显示器,并且即使物理监视器断开连接也能保持桌面环境稳定运行[^3]。 #### 测试与验证 最后一步是对刚刚所做的修改进行测试。可以通过VNC或其他远程桌面工具尝试登录到目标机器上来确认一切按预期运作。如果一切顺利,则可以在没有实际硬件的情况下正常使用GUI应用程序和服务了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值