Como alterar o GSettings sem o X11 em execução?

3

Eu tenho um script de instalação que personaliza a máquina de destino, executando cerca de duas dúzias de gsettings set de comandos. O problema é que isso só funciona se você executar o comando como o usuário certo. Se você executá-lo como root, ele não funciona.

Então eu inventei uma função de script que se parece com isso:

function GSET
{
    echo "gsettings set '$1' '$2' '$3'"
    sudo -u mango dbus-launch gsettings set "$1" "$2" "$3"
}

O script chama essa função várias dúzias de vezes, o que parece funcionar (ou seja, as configurações realmente mudam agora) e tudo é bom.

Bem, não totalmente: se eu executo isso na máquina que estou tentando configurar, parece funcionar muito bem. Se eu tentar executá-lo em nosso servidor de compilação em um ambiente chroot para criar uma imagem de instalação ... O servidor agora tem uma dúzia de dbus-daemon processos sendo executados nele. E toda vez que eu executo uma nova instalação, fico com mais e mais desses processos inúteis rodando, até que eventualmente o servidor exaure algum tipo de recurso (PIDs ou algo assim), e gsettings pára de funcionar completamente.

Então, minha pergunta: qual é a maneira correta de fazer gsettings funcionar? Eu vi outra resposta em algum lugar que sugeria a adição da opção --exit-with-session , mas isso simplesmente impediu o comando de funcionar. Existe alguma maneira de lançar um único daemon para todas as configurações e depois pará-lo depois ou algo do tipo?

    
por MathematicalOrchid 14.12.2016 / 16:15

1 resposta

1

Como você descobriu, dbus-launch cria um novo daemon D-Bus toda vez que é executado. Você pode usar dbus-launch e matá-lo quando terminar:

# Make the function
GSET () {
    sudo -u mango DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" gsettings set "$1" "$2" "$3"
}
# Launch the daemon
. <(sudo -u mango dbus-daemon --sh-syntax)
# Run as many commands as you need
GSET x1 y1 z1
GSET x2 y2 z2
...
# Kill the daemon
sudo -u mango kill "$DBUS_SESSION_BUS_PID"

Você poderia usar uma abordagem transacional baseada em shell para evitar chamar sudo repetidamente. Algo como:

script=$(mktemp gset-transaction.XXXXXXXXXX)
create_transaction () {
    printf '. <(dbus-launch --sh-syntax)\n' > "$script"
}
GSET () {
    printf 'gsettings set "%s" "%s" "%s"\n' "$1" "$2" "$3" >> "$script"
}
commit_transaction () {
    printf 'kill "$DBUS_SESSION_BUS_PID"\n' >> "$script"
    sudo -u mango bash -c "$script"
    # optionally:
    # rm "$script"
}

create_transaction
GSET x1 y1 z1
GSET x2 y2 z2
...
commit_transaction
    
por 14.12.2017 / 16:33