如何在不运行 X11 的情况下更改 GSettings?

如何在不运行 X11 的情况下更改 GSettings?

我有一个安装脚本,可以通过运行大约两打gsettings set命令来自定义目标计算机。问题是,只有当您以正确的用户身份运行该命令时,这才有效。如果你以 root 身份运行它,它根本不起作用。

所以我发明了一个脚本函数,如下所示:

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

然后该脚本调用该函数数十次,这似乎有效(即设置现在实际上发生了变化),并且一切都很好。

好吧,不完全是:如果我在我尝试配置的机器上运行它,它似乎工作得很好。如果我尝试在chroot环境中的构建服务器上运行它来创建安装映像...服务器dbus-daemon上现在有十几个进程正在运行。每次我运行新的安装版本时,都会留下越来越多的无用进程在运行,直到最终服务器耗尽某种资源(PID 或其他东西),并gsettings完全停止工作。

所以,我的问题是:什么是正确的怎样做gsettings工作?我在某个地方看到了另一个答案,建议添加--exit-with-session开关,但这根本就停止了命令的工作。有没有办法为所有设置启动一个守护进程,然后停止它或其他什么?

答案1

正如您所发现的,dbus-launch每次运行时都会创建一个新的 D-Bus 守护进程。您可以dbus-launch在完成后使用并杀死它:

# 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"

您可以使用基于 shell 的事务方法来避免sudo重复调用。就像是:

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

相关内容