RHEL下systemd服务中Bash脚本禁用gsettings快捷键失效问题
问题:systemd服务运行Qt锁屏工具时无法禁用GNOME键盘快捷键
我正在基于以下技术开发一款锁屏工具:
- Red Hat Enterprise Linux 7.6
- Qt Creator
- C++
核心需求是用户在锁屏界面无法使用任何键盘快捷键。目前在Qt Creator中调试时,通过执行以下脚本可以正常禁用快捷键,解锁时再重新启用:
#! /usr/bin/bash shortcuts=$(gsettings list-keys org.gnome.desktop.wm.keybindings); for x in $shortcuts; do echo "Disabling $x"; gsettings set org.gnome.desktop.wm.keybindings $x []; done
但将编译后的Qt程序通过systemd服务调用时,出现了问题:服务能正常启动并运行程序,查看journalctl日志可见echo "Disabling..."命令已执行,但我仍能使用键盘快捷键(比如按下ALT+F1可进入applications->system tools->settings->devices),快捷键并未被实际禁用。
我的testService.service配置如下:
[Unit] Description=testing screenlocker service After=graphical.target [Service] #Type=simple Type=exec Environment="DISPLAY=:0" #ExecStartPre=/home/user/Desktop/ScreenLocker/Source/disableShortcuts.sh ExecStart=/home/user/Desktop/ScreenLocker/Source/build-ScreenLocker-Desktop_Qt_5_3_0_GCC_64bit-Debug/Screenlocker TimeoutStartSec=0 [Install] WantedBy=default.target
我不确定是什么权限或设置导致该系统服务无法修改用户的键盘映射。
Qt相关代码如下:
main.cpp:
int main(int argc, char *argv[]) { QApplication a(argc, argv); // set current directory to build directory so QT looks for resources in the right spot // (before it would look in the directory above where PWD was and would have issues QDir::setCurrent(QCoreApplication::applicationDirPath()); // Disabling keyboard shortcuts QString qstr = QApplication::applicationDirPath(); QDir qdir = QDir(qstr); qdir.cdUp(); QString qstrpath = qdir.absoluteFilePath("disableShortcuts.sh"); qstrpath = QDir::toNativeSeparators(qstrpath); system(qPrintable(qstrpath)); ... }
mainwindow.cpp中按钮点击重置快捷键的逻辑:
void MainWindow::handleButton(){ QString usr = getUsername(); QString pswd = getPassword(); QCloseEvent *event; if(usr == "Ray" && pswd == "Theon"){ // Reenabling keyboard shortcuts QString qstr = QApplication::applicationDirPath(); QDir qdir = QDir(qstr); qdir.cdUp(); QString qstrpath = qdir.absoluteFilePath("resetShortcuts.sh"); qstrpath = QDir::toNativeSeparators(qstrpath); system(qPrintable(qstrpath)); setStyleSheet("background-color: blue"); event->setAccepted(true); this->close(); } } ...
我已尝试的方法:
- 使用ExecStartPre/ExecStopPost分别在锁屏工具启动前、停止后运行对应脚本,但未成功;
- 在.service文件中设置Type为simple和oneshot,试图避免其他服务抢占执行;
- 将Bash脚本权限改为777,确保无执行权限问题。
内容的提问来源于stack exchange,提问作者lkilgoretrout
相关产品推荐
相关产品推荐

