4

I have an installation script that customises the target machine by running about two-dozen gsettings set commands. Trouble is, that only works if you run the command as the right user. If you run it as root, it doesn't work at all.

So I invented a script function that looks like this:

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

The script then calls this function several dozen times, which seems to work (i.e., the settings actually change now), and all is good.

Well, not quite: If I run this on the machine I'm trying to configure, it seems to work great. If I try to run it on our build server in a chroot environment to create an installation image... The server now has a dozen dbus-daemon processes running on it. And every time I run a new installation build, I'm left with more and more of these useless processes running, until eventually the server exhausts some kind of resource (PIDs or something), and gsettings stops working completely.

So, my question: What is the correct way to make gsettings work? I saw another answer somewhere that suggested adding the --exit-with-session switch, but that just stopped the command working at all. Is there some way to launch a single daemon for all the settings and then stop it afterwards or something?

1
+500

As you have discovered, dbus-launch creates a new D-Bus daemon every time it is run. You can instead use dbus-launch and kill it when you are done:

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

You could use a shell-based transactional approach to avoid calling sudo repeatedly. Something like:

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
  • Thank you for helping me finally fix this infuriating problem... Here, have some rep. – MathematicalOrchid Dec 18 '17 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.