自动化任务

自动化任务

我需要在启动时运行该命令: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并收到此错误:

systemctl 的错误报告

我有一个问题,我做错了什么?

答案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

相关内容