以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
相关产品推荐
相关产品推荐

