xfconf-query load from file
Introduction
The wonderful xfce desktop environment provides a mechanism to inspect and modify your settings, similar to dconf. This tool is named xfconf-query, and it allows you to list and modify entries one at a time. Unfortunately, it does not provide a way to export to a file and import, the way dconf does (with standard redirection).
Save settings to file
For xfce, you can display the settings by specifying the channel:
xfconf-query -c thunar -lv
#place sample output here
You can save this to a file with output redirection, but you won’t be able to load this very easily from such a file.
To get the settings in a nicer format for saving to a text file, use this oneliner:
xfconf-query -l | sed -r -e '/Channels:/d' | while read line; do xfconf-query -lv -c "${line}" | sed -r -e "s/^/${line} /"; done > my-settings.xfconf
#place sample output here
xfconf-query load settings from file
I wrote a wrapper script that loads the settings from such a file. Please check out the full xfconf.sh script at gitlab.
Its basic use is very simple. Call the script with the settings file as the only parameter:
xfconf.sh mysettings.xfconf
Code walkthrough
#!/bin/sh
# File: /usr/share/bgconf/inc/xfconf.sh
# Author: bgstack15
# Startdate: 2017-09-17 08:10
# Title: Script that Loads Settings into Xfconf
# Purpose: To make a single interface for other bgconf scripts to call for loading an xfconf file
# History:
# 2017-06 Main research was done but put in separate bgconf scripts.
# 2017-09-17 I decided to separate it out to streamline the bgconf scripts themselves.
# Usage:
# In a script, determine that an xfconf file exists, then call:
# xfconf.sh mysettings.xfconf
# To generate a new xfconf file, you can run:
# xfconf-query -l | sed -r -e '/Channels:/d' | while read line; do xfconf-query -lv -c "${line}" | sed -r -e "s/^/${line} /"; done > outfile
# Reference:
# Improve:
# Document: Below this line
thisDE=xfce
thisDEconf=xfconf-query
infile="${1}"
# get DBUS_SESSION_BUS_ADDRESS of first DE process of this user
# reference: https://unix.stackexchange.com/questions/29128/how-to-read-environment-variables-of-a-process/29132#29132
tmpfile1="$( mktemp )"
if test -n "${SUDO_USER}"; then _user="${SUDO_USER}"; else _user="${USER}"; fi
cat /proc/$( ps -eu${_user} | grep -E "${thisDE}" | tail -n1 | awk '{print $1}' )/environ 2>/dev/null | tr '\0' '\n' | grep -E "DBUS_SESSION_BUS_ADDRESS|DISPLAY" > "${tmpfile1}"
test -f "${tmpfile1}" && test $( grep -cE "(DBUS_SESSION_BUS_ADDRESS|DISPLAY)=.+" "${tmpfile1}" 2>/dev/null ) -ge 2 || echo "$0 error: Skipping ${thisDE}: Could not find current session." 1>&2
chmod +rx "${tmpfile1}" 2>/dev/null
. "${tmpfile1}"
/bin/rm -f "${tmpfile1}" 1>/dev/null 2>&1
# Assume infile exists as a file
if test -n "$( cat "${infile}" 2>/dev/null )" && test -x "$( which "${thisDEconf}" )" && ps -ef | grep -qE "${thisDE}" && test -n "${DBUS_SESSION_BUS_ADDRESS}";
then
# get user of that directory
thisowner="$( stat -c '%U' "${infile}" )"
thisowneruid="$( stat -c '%u' "${infile}" )"
# xfce custom configuration
grep -viE '^\s*((#|;).*)?$' "${infile}" | while read channel attrib value;
do
# display output
#printf "channel=%s\tattrib=%s\tvalue\%s\n" "${channel}" "${attrib}" "${value}"
# provide data type. This needs to be researched before making a new .xfconf file.
_thistype=string
case "${attrib}" in
*last-separator-position) _thistype=integer ;;
*last-show-hidden|*misc-single-click) _thistype=bool ;;
esac
# make change
sudo su - "${thisowner}" -c "DISPLAY=${DISPLAY} DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS} ${thisDEconf} --create -t ${_thistype} -c ${channel} -p ${attrib} -s ${value}"
done
fi
/bin/rm -f "${tmpfile1}" 2>/dev/null
The line numbers here are different from the script on github, and probably will get outdated as I make improvements to this utility. So I will use line numbers for the version seen above. Also, this script was originally written as a small portion of a larger project to deploy my settings to a whole system. That’s why you’ll see the “sudo – su” and logic to determine file ownership, because it is being called by a command running with sudo.
Lines 23-31 find the running desktop environment for the user (or the user who called sudo) and grab the values for DBUS_SESSION_BUS_ADDRESS and DISPLAY that point to that running desktop environment. I don’t know a more official way, so I assembled this kludge over the course of this project. I’m rather fond of this logic despite the kludgeyness. You will observe on line 30 that this script actually dot sources a temp file with those variables. I actually first used this technique for loading conf files in an attempt to be more unix-like and use environment variables first, and then load in a conf file.
Line 34 calculates the requested file has contents, and the desktop environment really exists and is running, and one of the variables from the previous section is defined.
Lines 42-58 perform the actual import of settings from the file. The interesting regular expression is my official non-blank non-comment regex. For quick hand-typed oneliners, I normally just use ‘^$|^#’ but here I went with the fancier version that handles whitespace.
So the block reads three entries per line, the channel, item, and item value. Then it runs xfconf-query and plugs in the variable.
Lines 48-53 perform a manual type declaration based on hard-coded names. I don’t know how to query that from xfconf-query, so I had to use the graphical xfce settings tool to collect the exact names. You will definitely need to read through your xfconf files to make sure you include all the right options here. I suppose one could find a list of all the datatypes maybe from xfce’s documentation and parse it. I guess I’ll add that to the “Improve:” header.