Мне нужно выполнить эту команду при загрузке: 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 . Затем я проверяю состояние модуля: $ systemctl -l status swapkey.service и получаю эту ошибку:

сообщение об ошибке из systemctl

И у меня есть вопрос, что я делаю не так?

2 ответа2

3

что я делаю не так?

Вы пытаетесь сделать это из службы. Не пытайтесь делать вещи, связанные с X11, из службы.


Ну, первая проблема здесь в том, что ваш сервис хочет настроить параметры в Xorg, на сервере X11 ... но он не велел systemd ждать, пока Xorg не будет готов и доступен. Если модуль не перечисляет явно порядок (До =, После = и т.д.), Он будет запущен параллельно со всем остальным на стадии, и это довольно часто означает, что он запустится слишком рано.

К сожалению, в случае с Xorg нет ни одного юнита, который вы могли бы заказать. Хотя Xorg запускается "диспетчером дисплеев", таким как GDM или LightDM, вы не часто доберетесь до «After = lightdm.service», потому что это означает «после того, как сам диспетчер дисплеев готов» - это не значит msgstr "диспетчер дисплеев начал своё первое отображение". Так что ваше подразделение может все еще работать рано.

Вторая проблема в том, что вашей программе не сказано, к какому Xorg подключаться. На самом деле не существует такого понятия, как "сервер X11" или "сервер X11 по умолчанию"; он должен быть указан явно через переменную окружения $ DISPLAY. Ваши настольные приложения автоматически знают об этом, а службы - нет. (Одна из причин заключается в том, что может быть несколько экземпляров Xorg, например, по одному на каждого зарегистрированного пользователя.)

Это означает, что вашему сценарию нужно как-то угадать отображаемое число и поместить его в $ DISPLAY. Часто оно будет пронумеровано :0 , но это не гарантия.

Третья проблема заключается в том, что даже когда диспетчер дисплеев запускает свой первый дисплей и ваш скрипт успешно его находит, это на самом деле еще не ваш дисплей. Это просто экран входа в систему . После того, как вы войдете в систему, он будет удален (или спрятан), а новый запущен для вашего рабочего стола - так что ничто из того, что сделал ваш скрипт xcape , все равно не перенесется.


Правильный подход состоит в том, чтобы запускать такие инструменты не при загрузке, а при входе в систему, и запускать их должен сам рабочий стол (менеджер сеансов). Почти всегда будет доступен один из следующих методов:

  • файл .desktop внутри ~/.config/autostart/;
  • строка в сценарии оболочки ~/.xprofile (создайте, если она не существует);
  • строка в сценарии оболочки ~/.profile (внутри проверки "if [" $ DISPLAY "]");
1

Наконец, проблема решена благодаря гравитации. Я сделал файл с именем swapkey.desktop в ~/.config/autostart который содержит:

[Desktop Entry]
Name=Swapkey
Exec=/home/vitaly/.config/autostart-scripts/swapkey.sh
Terminal=false
Type=Application
StartupNotify=false

Также я пишу сценарий оболочки, который я поместил, как вы можете видеть выше, в папку, которую я создаю сам. Скрипт содержит:

#!/bin/bash
xcape -e 'Control_L=Escape'

И, я не знаю, было ли это необходимо или нет, я сделал его исполняемым с помощью chmod +x ... И вуаля, это работает как положено. PS Система, на которой я работаю - Manjaro linux

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .