我需要在启动时运行该命令:xcape -e 'Control_L=Escape'
。因此我编写了一个名为 swapkeys.sh 的脚本:
#!/bin/bash
xcape -e 'Control_L=Escape'
我使用以下命令使其可执行:
$chmod +x swapkeys.sh
然后我编写了名为 swapkey.service 的单元:
[Unit]
Description=Swapping keys from Esc >> Ctrl
[Service]
Type=oneshot
ExecStart=/usr/bin/local/swapkeys.sh
[Install]
WantedBy=multi-user.target
然后我运行:$systemctl enable swapkey.service
在我执行的操作之后:$ systemctl start swapkey.service
。然后我检查 Unit 的状态:$systemctl -l status swapkey.service
并收到此错误:
我有一个问题,我做错了什么?
答案1
我做错了什么?
您正在尝试通过服务执行此操作。请勿尝试通过服务执行与 X11 相关的事情。
嗯,这里的第一个问题是你的服务想要调整 Xorg(X11 服务器)中的参数……但它并没有告诉 systemd 实际等待直到 Xorg 准备就绪并可用。如果单元没有明确列出顺序(Before=、After= 等),它将被启动在平行下与舞台上的所有其他事物一样,这通常意味着它运行得太早。
不幸的是,在 Xorg 中,不是您可以针对任何单元进行命令。尽管 Xorg 是由“显示管理器”(例如 GDM 或 LightDM)启动的,但您通常无法通过“After=lightdm.service”获得任何结果,因为这仅表示“在显示管理器本身准备就绪之后” - 并不意味着“显示管理器已启动其第一个显示”。因此您的单元可能仍会提前运行。
第二个问题是你的程序没有被告知哪个Xorg 连接。实际上没有所谓的“该”X11 服务器或“默认”X11 服务器;必须通过 $DISPLAY 环境变量明确指定。您的桌面应用程序会自动知道它 - 服务不知道。(一个原因是很容易多种的Xorg 实例,例如每个登录用户一个。)
因此,这意味着您的脚本需要以某种方式猜测显示编号,并将其放入 $DISPLAY 中。通常它会被编号:0
,但这并不能保证。
第三个问题是,即使显示管理器启动了它的第一个显示器,并且你的脚本成功找到了它,但这实际上并不是你的尚未显示。这只是登录屏幕显示。登录后,它将被丢弃(或隐藏),并在您自己的桌面上启动一个新的 - 因此您的卡普无论如何,脚本都会继续存在。
正确的做法是启动这些工具而不是在启动时,但在登录,并让它们由您的桌面本身(会话管理器)启动。几乎总是可以使用以下方法之一:
- ~/.config/autostart/ 中的一个 .desktop 文件;
- ~/.xprofile shell 脚本中的一行(如果不存在则创建);
- ~/.profile shell 脚本中的一行(在“if [ "$DISPLAY" ]”检查里面);
答案2
最后,感谢 Grawity,问题得以解决。我创建了一个名为 swapkey.desktop 的文件,~/.config/autostart
其中包含:
[Desktop Entry]
Name=Swapkey
Exec=/home/vitaly/.config/autostart-scripts/swapkey.sh
Terminal=false
Type=Application
StartupNotify=false
我还编写了一个 shell 脚本,如上所示,将其放在我自己创建的文件夹中。该脚本包含:
#!/bin/bash
xcape -e 'Control_L=Escape'
而且,我不知道这是否必要,我用 使它可执行chmod +x ...
。瞧,它按预期工作了。PS 我使用的系统 - Manjaro linux