You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

以root身份在Linux RDP中指定非root用户DISPLAY运行Headful Playwright报错求助

解决root身份在xrdp+GNOME环境下运行Headful Playwright的DISPLAY问题

问题背景

  • 运行环境:Linux系统,搭配xrdp远程桌面与GNOME桌面环境
  • 核心需求:以root身份运行Express服务器,通过HTTP请求触发Headful模式的Playwright脚本;脚本运行时,让连接RDP的非root用户能看到自动打开的浏览器,同时避免RDP用户直接访问脚本文件
  • 当前异常:以非root用户运行Express服务器时脚本正常工作,但切换为root身份运行时,触发脚本会抛出「Missing X server or $DISPLAY」错误

当前使用代码

import playwright from 'playwright';
import { exec } from 'child_process'; // 原代码缺失此导入,需补充

const data = exec(
  "loginctl show-session $(loginctl -a show-user rdp | grep Display | sed 's/Display.//g') | grep Display | sed 's/Display.//g'",
);

if (data.stdout.length) {
  process.env['DISPLAY'] = data.stdout.replace(/\n/g, ''); // 尝试设置DISPLAY为例如:10.0
}

(async () => {
  // Setup
  const browser = await playwright.chromium.launch({
    headless: false
  });
  const page = await browser.newPage();

  // 访问目标页面
  await page.goto('https://example.com/');

  // 关闭浏览器
  await browser.close();
})();

解决方案

1. 修正DISPLAY变量的获取逻辑

原命令存在冗余,且未处理会话ID获取失败的情况,可简化为更可靠的命令:

loginctl show-user rdp -p Display --value

此命令直接输出指定用户rdp的DISPLAY值,无需多层管道处理。

2. 授权root访问非root用户的X显示服务

root用户默认没有权限访问普通用户的X Server,需要完成两步授权:

  • 设置XAUTHORITY环境变量:X Server通过授权文件验证访问权限,需指定非root用户的授权文件路径,通常为/home/rdp/.Xauthority
  • 临时添加root访问权限:执行xhost +si:localuser:root,允许root访问当前用户的X显示

3. 完善后的代码实现

import playwright from 'playwright';
import { execSync } from 'child_process'; // 使用execSync同步获取结果,避免异步问题

try {
  // 获取非root用户的DISPLAY值
  const display = execSync('loginctl show-user rdp -p Display --value', { encoding: 'utf8' }).trim();
  if (!display) {
    throw new Error('未获取到非root用户的DISPLAY变量');
  }

  // 设置DISPLAY环境变量
  process.env.DISPLAY = display;
  // 设置XAUTHORITY为非root用户的授权文件路径
  process.env.XAUTHORITY = '/home/rdp/.Xauthority';

  // 授权root访问X显示服务(需确保非root用户已登录RDP,且此命令在用户会话中执行过)
  execSync(`xhost +si:localuser:root -display ${display}`);

  // 启动Headful浏览器
  const browser = await playwright.chromium.launch({
    headless: false,
    // 可选:指定浏览器可执行路径,避免root找不到默认路径
    executablePath: '/usr/bin/google-chrome' // 按需替换为实际浏览器路径
  });
  const page = await browser.newPage();

  await page.goto('https://example.com/');

  // 业务逻辑完成后关闭浏览器
  // await browser.close();
} catch (error) {
  console.error('脚本执行失败:', error.message);
}

关键说明

  • 使用execSync而非exec:确保在启动浏览器前已经获取并设置好环境变量,避免异步导致的时序问题
  • XAUTHORITY变量:必须指定,否则X Server会拒绝root的访问请求
  • xhost授权:若希望永久生效,可将xhost +si:localuser:root添加到非root用户的.bashrc或.profile中,每次登录RDP时自动执行

内容的提问来源于stack exchange,提问作者ABDELJALIL AIT ETALEB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:42:20