我的笔记本电脑键盘很差,但 Lily58 好得多,所以我写了一个 bash 脚本来禁用我的笔记本电脑键盘,这样我就可以将 Lily58 放在上面,然后再重新启用它。但是当我禁用笔记本电脑键盘时,如果我将笔记本电脑挂起,它就会保持禁用状态,而我希望它在恢复时自动重新启用。所以我写了一个简短的 bash 脚本
#!/bin/bash
fconfig="/home/alex/.keyboard"
id=$(xinput | grep AT | sed -n '2,2p' | awk '{print $7}' | sed 's/[^0-9]*//g')
if [ -f $fconfig ]; then
read -r var< $fconfig
if [ "$var" = "disabled" ]; then
xinput enable $id
echo "enabled" > $fconfig
fi
fi
/home/alex/.keyboard
这将检查跟踪键盘是否启用的文件中是否存在“disabled” ,如果是,则xinput
使用通过筛选输出获得的 id 运行以重新启用,xinput
方式与 的定义相同id
,然后设置/home/alex/.keyboard
为enabled
。当我从终端触发 bash 脚本时,此操作可以正常工作,但是当我启动 systemd 服务时
[Unit]
Description=This service enables your keyboard after suspension
PartOf=graphical-session.target
[Service]
Type=oneshot
ExecStart=/home/alex/bash/enable-keyboard
[Install]
WantedBy=multi-user.target
我想在暂停后运行,它设置/home/alex/.keyboard
为enabled
但实际上并没有重新启用我的键盘。此外,journalctl -xeu enable-keyboard.service
没有指示任何错误:
Jul 17 22:16:25 gentoolaptop systemd[795]: Starting This service enables your keyboard after suspension.
░░ Subject: A start job for unit UNIT has begun execution
░░ Defined-By: systemd
░░ Support: https://gentoo.org/support/
░░
░░ A start job for unit UNIT has begun execution.
░░
░░ The job identifier is 8969.
Jul 17 22:16:25 gentoolaptop systemd[795]: Finished This service enables your keyboard after suspension.
░░ Subject: A start job for unit UNIT has finished successfully
░░ Defined-By: systemd
░░ Support: https://gentoo.org/support/
░░
░░ A start job for unit UNIT has finished successfully.
░░
░░ The job identifier is 8969.
出了什么问题?
编辑:如果我将一个子句放入脚本中以将输出打印xinput
到文件中,则输出将由一个空行组成。
编辑:的输出systemctl --user status dbus.socket dbus.service
是
● dbus.socket - D-Bus User Message Bus Socket
Loaded: loaded (/usr/lib/systemd/user/dbus.socket; static)
Active: active (running) since Thu 2024-07-18 17:22:54 CEST; 5 days ago
Triggers: ● dbus.service
Listen: /run/user/1000/bus (Stream)
Tasks: 0 (limit: 47295)
Memory: 4.0K (peak: 1.5M)
CPU: 8ms
CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/dbus.socket
Jul 18 17:22:54 gentoolaptop systemd[830]: Starting D-Bus User Message Bus Socket...
Jul 18 17:22:54 gentoolaptop systemd[830]: Listening on D-Bus User Message Bus Socket.
● dbus.service - D-Bus User Message Bus
Loaded: loaded (/usr/lib/systemd/user/dbus.service; static)
Active: active (running) since Thu 2024-07-18 17:22:54 CEST; 5 days ago
TriggeredBy: ● dbus.socket
Docs: man:dbus-daemon(1)
Main PID: 897 (dbus-daemon)
Tasks: 1 (limit: 47295)
Memory: 1.0M (peak: 1.7M)
CPU: 252ms
CGroup: /user.slice/user-1000.slice/[email protected]/session.slice/dbus.service
└─897 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
Jul 23 16:55:45 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.149' (uid=1000 pid=105378 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:11:00 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 23 17:19:31 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.152' (uid=1000 pid=106706 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:21:31 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 23 17:30:31 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.153' (uid=1000 pid=108520 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:32:31 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 24 14:15:05 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.164' (uid=1000 pid=126615 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 24 14:17:05 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 24 14:26:05 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.165' (uid=1000 pid=127823 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 24 14:28:05 gentoolaptop dbus-daemon[897]: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
的输出ls -l /run/user/*/bus
是
srw-rw-rw- 1 alex alex 0 2024-07-18 17:22 /run/user/1000/bus
```.
注意:此答案假定您的桌面环境会将
DISPLAY
环境XAUTHORITY
变量导入到 systemd 用户管理器,并且您始终使用相同的用户帐户登录。xinput
是一个 X 实用程序。换句话说,它是一个 X 客户端。因此,您需要使用DISPLAY
环境变量来指示它应该与哪个 X 服务器通信(即使只有一个正在运行),并允许它使用环境连接到该XAUTHORITY
服务器。棘手的是,似乎没有一种巧妙的方法可以让登录用户的用户管理器在系统休眠(和恢复)时启动用户服务。此外,从技术上讲,您可以让多个用户登录并运行多个 X 服务器,因此实际上没有办法“改进”这种情况下的运作方式,至少在不依赖一些肮脏假设的情况下是没有办法的。
话虽如此,只要您同意这些假设,您仍然可以“硬编码”解决方案:
systemd-run --user
可以在系统服务中使用runuser
,因此请勿将其替换为User=
。另外,请勿将其用作用户服务。编辑:由于看起来您的方法似乎
runuser
没有按预期工作,您可能想尝试以下版本:确保在以下行之前
~/.xinitrc
至少包含一行源/etc/X11/xinit/xinitrc.d/50-systemd-user.sh
(假设该文件存在于您的系统中)exec
:启用服务后,每次系统恢复后(即
sleep.target
停止时,因此有PartOf=
和ExecStop=
)都应调用该脚本。PS 您甚至可以在脚本中硬编码(
DISPLAY
)。在这种情况下应该可以工作。XAUTHORITY
export
ExecStop=/home/alex/bash/enable-keyboard
如果您还需要
/home/alex/bash/enable-keyboard
在图形登录时运行,请为其编写另一个服务(这次它可能应该是用户服务):确保使用 启用了此服务
systemctl --user
。此外,只有当您的桌面环境graphical-session.target
在图形登录时被真正拉入时,它才会起作用。(注意:当您使用时
startx
,目标很可能不会被拉入。您应该在~/.xinitrc
该exec
行之前调用(而不是源,尽管它可能没问题)您的脚本,或者如果您真的希望用户管理器调用它,请使用systemctl --user
启动目标或服务~/.xinitrc
(再次,在该exec
行之前)。)它不能是系统服务的原因是,假设脚本需要在用户会话中的 X 服务器启动后运行,您需要在脚本中轮询(或滥用
Restart=
)并等到那时。(但当然,您可以让它与显示管理器的 X 服务器对话(如果有的话),并且效果会保留。但随后您将需要找出并硬编码相应的DISPLAY
和XAUTHORITY
,并且根据显示管理器如何与 systemd“交互”,它可能注定是“不雅的”,您将需要一些令人讨厌的“睡眠 5”。)您甚至可以直接使用
xinitrc.d
脚本、XDG 自动启动或在您的 DE 下运行的任何脚本来调用该脚本。您说得对,xinput 没有输出。我已经测试过了。
系统服务单元在 Xorg 的范围/环境之外运行。
您必须将您的单元放入 中
/usr/lib/systemd/user/myservice.service
,然后您才能获得完全访问权限。我尝试过。在或更好的是,在中创建了一个服务myservice.service
/usr/lib/systemd/user
/home/[username]/.config/systemd/user
我的服务脚本:
我正在读取tmp 文件夹中名为pause_wakeup的文件。 如果pause_wakeup包含"true",则将xinput回显到tmp文件夹中名为xinput 的文件。您可以在此处添加代码,而不是回显。 然后将 false写入pause_wakeup。
我将把另一个名为suspension_wakeup(可执行脚本)的文件放入
/usr/lib/systemd/system-sleep
此脚本在tmp 文件夹中的 pause_wakeup 文件中写入“true”。这会导致服务单元回显 xinput 或执行您的工作(如果您插入该内容)。
该服务已启用:
systemctl --user enable myservice.service
并开始
systemctl --user start myservice.service
您必须在每个 systemctl 命令的“systemctl”后面加上“--user”
每次计算机进入睡眠状态并唤醒时,这种方法都有效。
更好的办法是让脚本
/usr/lib/systemd/system-sleep
改变键盘。但我试了又试,没有解决办法。也许你有什么想法?如果你有,请告诉我。