D-Bus
如何在不執行 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
開關的答案,但這只是停止了命令的工作。有沒有辦法為所有設置啟動一個守護程序,然後再停止它或其他什麼?
正如您所發現的,
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