AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 780347
Accepted
Alexander Praehauser
Alexander Praehauser
Asked: 2024-07-18 04:30:50 +0800 CST2024-07-18 04:30:50 +0800 CST 2024-07-18 04:30:50 +0800 CST

Systemd-user-service para ativar o teclado não dá erro, mas não funciona

  • 772

Eu tenho um teclado de laptop ruim e um Lily58 muito melhor, então escrevi um script bash para poder desabilitar o teclado do meu laptop para que eu possa colocar o Lily58 nele e reativá-lo depois. Mas quando eu desativo o teclado do laptop, ele permanece desativado se eu colocar o laptop em suspensão, enquanto eu preferiria que ele fosse reativado automaticamente na retomada. Então eu escrevi um pequeno script 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

Isso verifica se "desativado" está no arquivo /home/alex/.keyboardque rastreia se o teclado está ativado e, se estiver, é executado xinputpara reativar usando o ID obtido ao examinar a saída xinput da maneira usada na definição de e id, em seguida, definir /home/alex/.keyboardcomo enabled. Isso funciona como deveria quando eu aciono o script bash do terminal, mas quando eu inicio o serviço 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

que desejo executar após a suspensão, ele é definido, /home/alex/.keyboardmas enabledna verdade não reativa meu teclado. Além disso, journalctl -xeu enable-keyboard.servicenão indica nenhum erro:

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.

O que está errado?

Editar: se eu colocar uma cláusula no script para imprimir a saída xinputem um arquivo, a saída consistirá em uma linha vazia.

Editar: a saída de 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)

A saída de ls -l /run/user/*/busé

srw-rw-rw-   1 alex           alex            0 2024-07-18 17:22 /run/user/1000/bus
```.
systemd
  • 2 2 respostas
  • 83 Views

2 respostas

  • Voted
  1. Best Answer
    Tom Yan
    2024-07-21T19:00:03+08:002024-07-21T19:00:03+08:00

    Nota: Esta resposta pressupõe que a variável de ambiente DISPLAYe XAUTHORITYseria importada para o gerenciador de usuários do systemd pelo seu ambiente de desktop e que você sempre efetua login com a mesma conta de usuário.

    xinputé um utilitário X. Em outras palavras, é um cliente X. Portanto, você precisará indicar com qual servidor X ele deve se comunicar (mesmo que haja apenas um em execução) com a DISPLAYvariável de ambiente e permitir que ele se conecte a ele com o XAUTHORITYambiente.

    O complicado é que não parece haver uma maneira legal de fazer com que o(s) gerente(s) de usuário(s) conectado(s) obtenha(m) o serviço do usuário durante a suspensão do sistema (e retome). Além disso, tecnicamente você pode ter vários usuários logados e vários servidores X em execução, então não há realmente nenhuma maneira de "melhorar" como as coisas funcionam em um cenário como este, pelo menos não sem confiar em algumas suposições sujas.

    Dito isso, você ainda pode "codificar" uma solução, desde que esteja de acordo com essas suposições:

    [Unit]
    Description=This service enables your keyboard after suspension
    PartOf=sleep.target
    Before=sleep.target
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/bin/true
    ExecStop=/usr/bin/runuser alex -c 'systemd-run --user /home/alex/bash/enable-keyboard'
    
    [Install]
    WantedBy=sleep.target
    

    systemd-run --useré possível no serviço do sistemarunuser com , portanto não o substitua por User=. Além disso, não o use como um serviço de usuário .


    EDIT: Como parece que de alguma forma o seu runusernão funciona conforme o esperado, você pode tentar a seguinte versão:

    [Unit]
    Description=This service enables your keyboard after suspension
    PartOf=sleep.target
    Before=sleep.target
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    User=alex
    Environment=XDG_RUNTIME_DIR=/run/user/1000 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
    ExecStart=/usr/bin/true
    ExecStop=/usr/bin/systemd-run --user /home/alex/bash/enable-keyboard
    
    [Install]
    WantedBy=sleep.target
    

    Certifique-se de que ~/.xinitrcconsiste em pelo menos uma linha dessa origem /etc/X11/xinit/xinitrc.d/50-systemd-user.sh (assumindo que o arquivo existe em seu sistema) antes da execlinha:

    . /etc/X11/xinit/xinitrc.d/50-systemd-user.sh
    

    Com o serviço habilitado, o script deve ser chamado sempre após a reinicialização do sistema (que é quando sleep.targetseria interrompido, daí o PartOf=e ExecStop=).

    PS Você pode até mesmo codificar DISPLAYe XAUTHORITYdentro do seu script ( export). Nesse caso ExecStop=/home/alex/bash/enable-keyboarddeve funcionar.


    Se você também precisar /home/alex/bash/enable-keyboardser executado no login gráfico, escreva outro serviço para ele (desta vez provavelmente deverá ser um serviço de usuário ):

    [Unit]
    Description=This service enables your keyboard after suspension
    After=graphical-session.target
    
    [Service]
    Type=oneshot
    ExecStart=/home/alex/bash/enable-keyboard
    
    [Install]
    WantedBy=graphical-session.target
    

    Certifique-se de ativar este serviço com systemctl --user. Além disso, funcionaria apenas se o seu ambiente de área de trabalho fosse realmente graphical-session.targetativado no login gráfico.

    (NOTA: quando você usa startx, muito provavelmente o alvo não será puxado. Você deve apenas chamar (não a fonte, mesmo que possa ser adequado para isso) seu script antes ~/.xinitrcda execlinha, ou se você realmente deseja o gerenciador de usuários para chamá-lo, use systemctl --userpara iniciar o destino ou o serviço em seu ~/.xinitrc(novamente, antes da execlinha) .

    A razão pela qual não pode ser um serviço do sistema é que, supondo que o script precise ser executado após o servidor X na sessão do usuário ser iniciado, você precisaria pesquisar o script (ou abusar Restart=) e esperar até então. (Mas é claro, há uma chance de você simplesmente fazer com que ele fale com o servidor X do gerenciador de exibição, se houver, e que o efeito seja mantido. Mas então você precisará descobrir e codificar o correspondente DISPLAYe XAUTHORITY, e dependendo de como o gerenciador de exibição "interage" com o systemd, ele pode estar fadado a ser "atrevido" e você precisará de um desagradável "sono 5".)

    Você pode até mesmo chamar o script com um xinitrc.dscript, inicialização automática do XDG ou o que quer que funcione no seu DE.

    • 1
  2. Schmaehgrunza
    2024-07-20T00:16:55+08:002024-07-20T00:16:55+08:00

    Você está certo, o xinput não produz saída. Eu testei isso.
    As unidades de serviço do sistema são executadas fora do escopo/ambiente do Xorg.
    Você tem que colocar sua unidade /usr/lib/systemd/user/myservice.service, então você terá acesso total.

    O que eu tentei. Criou um serviço myservice.service em /usr/lib/systemd/userou melhor em/home/[username]/.config/systemd/user

    [Unit]
    Description=test
    
    [Service]
    Type=simple
    Restart=on-failure
    ExecStart=absolute path to service script
    
    [Install]
    WantedBy=graphical-session.target
    

    meu script de serviço:

    #!/usr/bin/bash
    while :; do
       if [[ -a "/tmp/suspension_wakeup" ]]; then
          wake_up=$(< /tmp/suspension_wakeup);
          if [[ $wake_up == "true" ]]; then
             echo "$(xinput)" > /tmp/xinput
             echo "false" > /tmp/suspension_wakeup
          fi
       fi
       sleep 10
    done
    

    Estou lendo um arquivo na pasta tmp chamadosuspension_wakeup . Sesuspension_wakeup
    contiver "true" , ​​então ecoe xinput para um arquivo na pasta tmp chamado xinput . Aqui você pode adicionar seu código, em vez de ecoar. então escreva false parasuspension_wakeup .

    Vou colocar outro arquivo chamadosuspension_wakeup ( script executável) em/usr/lib/systemd/system-sleep

    #!/usr/bin/bash
    [[ $1 == "post" ]] && { umask 0111; echo "true" > /tmp/suspension_wakeup; }
    

    este script escreve "true" no arquivosuspension_wakeup na pasta tmp . Isso faz com que a unidade de serviço ecoe o xinput ou faça suas coisas, se você inserir isso.

    o serviço é habilitado com:
    systemctl --user enable myservice.service

    e começou com
    systemctl --user start myservice.service

    você tem que colocar "--user" depois de "systemctl" para cada comando systemctl

    Isso funcionou, toda vez que o computador entra em suspensão e acorda.

    Melhor seria deixar o script /usr/lib/systemd/system-sleepmudar o teclado. Mas eu tentei e tentei sem solução. Talvez você tenha uma ideia? Deixe-me saber, se você conseguiu.

    • 0

relate perguntas

  • Níveis diferenciadores no journalctl

  • Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _

  • systemd: como posso executar um script no início de um serviço, sem editar a definição do serviço

  • Use o suporte de watchdog do systemd para reiniciar o aplicativo

  • Inicie/pare o serviço systemd usando o atalho de teclado [fechado]

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve