GSettings: H Registry του Linux

Αν υπάρχει κάτι απωθητικό στα **Windows** είναι το περιβόητο **Registry** και η εντολή **regedit**. Αλλά λίγοι ξέρουν πως υπάρχει το ίδιο πράγμα και στο **Desktop Linux**. Έχει γίνει το **Linux** σαν τα **Windows** λοιπόν; Είναι το ίδιο; Σε τι κόσμο θα φέρουμε τα παιδιά μας; Ας το διαπιστώσουμε...

Στην πράξη

Ας δούμε μερικούς τρόπους με τους οποίους μπορούμε να αλλάξουμε το background της οθόνης. Τον πρώτο τον ξέρουμε μέσα από κάποιο παράθυρο ρυθμίσεων. Ένας άλλος τρόπος είναι μέσα από το dconf-editor που συνήθως δεν είναι εγκατεστημένο. Μέσα από αυτό θα πάμε στην διαδρομή /org/gnome/desktop/background και θα το αλλάξουμε σε κάτι άλλο:

Πριν προχωρήσουμε μελετήστε λίγο την εικόνα. Υπάρχει μια περιγραφή της ρύθμισης, ο τύπος της τιμής που παίρνει και μια προκαθορισμένη τιμή. Και ότι αλλαγές κάνουμε θα γίνουν αυτόματα. Ας κάνουμε ένα ακόμα πείραμα. Κρατήστε ανοικτό το dconf-editor και αλλάξτε το background με τον τρόπο που ξέρετε. Δείτε πως η αλλαγές συντονίζονται αυτόματα. Είδαμε στην πράξη την δύναμη του Linux Registry GSettings/Dconf. Αλλά αν θέλουμε από το τερματικό; Και τι είναι αυτό το schema; Θα το δούμε παρακάτω, αλλά πρώτα λίγη θεωρία.

Βασικοί ορισμοί

GSettings

Το GSettings είναι ένα API δηλαδή μια προγραμματική διασύνδεση για προγραμματιστές που επιτρέπει σε μια εφαρμογή να αποθηκεύει ρυθμίσεις

Dconf

Το Dconf είναι μια βάση δεδομένων που αποθηκεύονται οι ρυθμίσεις. Πριν από αυτά είχαμε το GConf το οποίο δεν χρησιμοποιείται ποια, αλλά πιθανά να υπάρχει κάποια παλιά εφαρμογή που να το χρησιμοποιεί ακόμα [λίστα]. Κύρια διαφορά είναι πως το Dconf χρησιμοποιεί δυαδικά αρχεία για την αποθήκευση, αντί για αρχεία κειμένου.

gsettings

Αυτό είναι μια εφαρμογή που μας επιτρέπει να αλλάζουμε ή να βλέπουμε της ρυθμίσεις από το τερματικό. Μπορούμε να αλληλεπιδράσουμε απευθείας με το dconf (με την εντολή dconf) αλλά καλύτερα να μάθουμε την χρήση του gsettings.

Τεχνικά το Dconf υλοποιείται μέσα στο GSettings σαν βιβλιοθήκη τμήμα της glib [code]. Αν ένα πρόγραμμα γίνει porting στα Windows θα χρησιμοποιήσει την registry. Είναι μια βάση δεδομένων (τεχνικά ένα key/value store) που έχει βελτιστοποιηθεί για ανάγνωση χωρίς κλήσεις συστήματος. Η εγράφη είναι μια άλλη ιστορία και θα γίνει με κλήση μιας υπηρεσίας DBus [DBus]. Το DBus είναι αυτό που θα φροντίσει οι αλλαγές σε μια ρύθμιση να πάνε σε όσες εφαρμογές τις ενδιαφέρει.

Για την ώρα δεν γίνεται χρήση του PolicyKit [polkit] αλλά είναι στο πλάνο.

Ένας διαχειριστής μπορεί να πειράξει τις ρυθμίσεις για όλους τους χρήστες ή ακόμα και να κλειδώσει μια ρύθμιση. Δεν χρησιμοποιούν όλες οι εφαρμογές το GSettings με το Gimp και το Inkscape να είναι κάποιες αξιοσημείωτες εξαιρέσεις, καθώς και οι εφαρμογές του KDE.

schemas

Που όμως ξέρει η βάση δεδομένων τι επιτρεπτές τιμές για να μας τις δείξει το dconf-editor; Θα πάμε στον κατάλογο /usr/share/glib-2.0/schemas και εκεί θα βρούμε το αρχείο org.gnome.desktop.background.gschema.xml που θα περιέχει τα παρακάτω:

<?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="gsettings-desktop-schemas">
  <schema id="org.gnome.desktop.background" path="/org/gnome/desktop/background/">
    ...
    <key name="picture-uri" type="s">
      <default>'file:///usr/share/backgrounds/gnome/adwaita-timed.xml'</default>
      <summary>Picture URI</summary>
      <description>
        URI to use for the background image. Note that the backend only supports
        local (file://) URIs.
      </description>
    </key>
    ...
  </schema>
</schemalist>

Και βρήκαμε την πληροφορία. Τα βοηθητικά κείμενα, και το ότι είναι κείμενο (string). Δεν τελειώνει εδώ η ιστορία, ίσως προσέξατε πως η προκαθορισμένη τιμή είναι αυτή του gnome και κάπου η διανομή έχει θέσει διαφορετική εξ’ ορισμού τιμή. Πώς έγινε αυτό; Στον ίδιο φάκελο θα δούμε και ένα αρχείο με όνομα /usr/share/glib-2.0/schemas/50_pop-default-settings.gschema.override που μεταξύ άλλων περιέχει το

[org.gnome.desktop.background]
picture-uri = 'file:///usr/share/backgrounds/pop/kate-hazen-pop-retro1.png'

Επίσης κάθε schema θα πρέπει να γίνει compile για να ενσωματωθεί η πληροφορία στην βάση, κάτι που θα γίνει αυτόματα κατά την εγκατάσταση της εφαρμογής. Επίσης ίσως να θέλουμε να κλειδώσουμε κάποια ρύθμιση. Αλλά αυτά αφορούν τους διαχειριστές συστημάτων και όχι εμάς τους «απλούς» χρήστες, οπότε ας τα αφήσουμε για την ώρα. Ίσως σε κάποιο άλλο άρθρο. Αρκεί για την ώρα να καταλάβουμε λίγο την δομή.

Στην πράξη, μέρος δεύτερον

Θα ξανακάνουμε το πείραμα της αλλαγής της εικόνας στο background, αλλά αυτή την φορά θα έχουμε ένα τερματικό να τρέχει την εντολή dconf watch /

Ήρθε η ώρα να κάνουμε το ίδιο από το τερματικό

dconf read  /org/gnome/desktop/background/picture-uri

και για εγγραφή

dconf write  /org/gnome/desktop/background/picture-uri 
   "'file:///usr/share/backgrounds/pop/kate-hazen-mort1mer.png'"

Προσέξτε πως για να καταλάβει των είναι κείμενο (string) έβαλα την τιμή μέσα σε διπλά εισαγωγικά, και πως η τιμή πρέπει να έχει μονά εισαγωγικά. Έτσι θέλει μας αρέσει δεν μας αρέσει :grinning: [περισσότερα].

Αλλά τουλάχιστον μπορείς να κάνεις και αυτό:

Με το gsettings

Ας δούμε πως μπορούμε να το κάνουμε με το gsettings.

settings get org.gnome.desktop.background picture-uri 

και

gsettings set org.gnome.desktop.background picture-uri 
"'file:///usr/share/backgrounds/pop/kate-hazen-mort1mer.png'"

H δομή είναι περίπου ίδια, αλλά δίνουμε χωριστά το schema το κλειδί και την τιμή. Τα πάντα χωρίζονται με τελεία, αντί να μοιάζουν με διαδρομές αρχείων. Προτιμώ το dconf αλλά καλύτερα να μάθεις το gsettings.

Relocatable schema

Αλλά μέχρι στιγμής είδαμε μόνο απλές περιπτώσεις. Κάποιες φορές έχουμε τα λεγόμενα relocatable schema, όπου μια εφαρμογή έχει “πίνακες ρυθμίσεων”. Για παράδειγμα δείτε (με το dconf-editor) την διαδρομή /org/gnome/terminal/legacy/ και πως η εφαρμογή του τερματικού έχει πολλά προφίλ, το καθένα με τις ρυθμίσεις του. Η εντολή gsettings list-relocatable-schemas θα μας δώσει άλλα παραδείγματα.

Το dconf είναι μια απλή βάση δεδομένων, τα πάντα τα βλέπει σαν διαδρομές και δεν καταλαβαίνει το νόημα, μόνο τον τύπο της τιμής (κείμενο, αριθμός, κλπ). Το GSettings καταλαβαίνει περισσότερα για το τι σημαίνει μια τιμή. Για τον λόγο αυτό είναι προτιμότερο να δίνουμε χωριστά το κλειδί και το schema και να προτιμούμε το gsettings.

Ας δούμε (χωρίς πολλές εξηγήσεις) την χρήση του gsettings σε μια τέτοια περίπτωση

profile=$(gsettings get org.gnome.Terminal.ProfilesList default)
profile=${profile:1:-1} # remove leading and trailing single quotes
gsettings set "org.gnome.Terminal.Legacy.Profile:/org/gnome/terminal/legacy/profiles:/:$profile/" default-size-columns 150

Για περισσότερα στο FAQ.

Χρήσιμα κόλπα

gnome extensions

Ας δούμε πως μπορούμε να αλλάξουμε τις ρυθμίσεις ενός gnome extension από την γραμμή εντολών. Οι επεκτάσεις που έχουμε εγκαταστήσει είναι στον κατάλογο ~/.local/share/gnome-shell/extensions/ και κάθε μια επέκταση περιέχει συνήθως ένα φάκελλο με όνομα schema που περιέχει το αρχείο XML (καθώς και σε μορφή compile). Θα πρέπει να δώσουμε αυτόν τον κατάλογο. Για παράδειγμα (σε μια γραμμή)

gsettings 
   --schemadir  ~/.local/share/gnome-shell/extensions/night-light-slider.timur@linux.com/schemas 
  list-recursively 
  org.gnome.shell.extensions.nightlightslider

και θα πάρουμε την λίστα των κλειδιών για να προχωρήσουμε παρακάτω…

Λίστα όλων των ρυθμίσεων

Τέλος ένα χρήσιμο σκριπτάκι που βρήκα εδώ και εδώ, που δείχνει τις περισσότερες ρυθμίσεις (τουλάχιστον τις απλές και ίσως φανεί χρήσιμο.

#!/bin/bash
# Gnome 3 can be customised from the command line via the gsettings command
# This script should help you to find what you're looking for by
# listing the ranges for all keys for each schema

for schema in $(gsettings list-schemas | sort)
do
    for key in $(gsettings list-keys $schema | sort)
    do
        value="$(gsettings range $schema $key | tr "\n" " ")"
        echo "$schema :: $key :: $value"
    done
done

Επαναφορά όλων των ρυθμίσεων

Μερικές φορές έχουμε πειράξει τόσες ρυθμίσεις που η μόνη λύση είναι να κάνουμε επαναφορά στις αρχικές για να ξεκινήσουμε από την αρχή σε μια καθαρή κατάσταση. Θα βρούμε με το dconf-editor μια πατρική διαδρομή και

gsettings reset-recursively org.cinnamon    # cinnamon
gsettings reset-recursively org.mate.panel  # mate panel
gsettings reset-recursively org.gnome       # all gnome apps

Αντίγραφά ασφαλείας και μεταφορά ρυθμίσεων

Θα χρησιμοποιήσουμε το dconf για να αποθηκεύσουμε τις ρυθμίσεις σε ένα αρχείο

dconf dump /org/gnome/ > all_gnome_settings

αυτό θα μοιάζει κάπως έτσι

....
[desktop/background]
color-shading-type='solid'
draw-background=true
picture-options='zoom'
picture-uri='file:///usr/share/backgrounds/pop/kate-hazen-fractal-mountains.png'
primary-color='#000000'
secondary-color='#000000'
....

και με την παρακάτω εντολή επαναφέρουμε τις ρυθμίσεις ή τις μεταφέρουμε σε άλλο μηχάνημα

dconf load /org/gnome/ < my_gnome_settings

Μαζικές ρυθμίσεις

Επεκτείνοντας τον προηγούμενο τρόπο μπορούμε να βάλουμε τις ρυθμίσεις που αλλάζουμε όταν εγκαθιστούμε το λειτουργικό και να τις έχουμε σε ένα αρχείο. Σε αυτή την περίπτωση είναι καλύτερο να έχουμε πλήρη διαδρομή δηλαδή το προηγούμενο να είναι

...
[org/gnome/desktop/background]
...

και να κάνουμε επαναφορά με

dconf load / < my_gnome_settings

Απομακρυσμένη ρύθμιση

H αλλαγή των ρυθμίσεων είδαμε ότι γίνεται μέσα από το DBUS. Αν συνδεθούμε σε ένα απομακρυσμένο σύστημα με ssh και θέλουμε να αλλάξουμε μια ρύθμιση θα πρέπει να ξέρουμε την διεύθυνση του DBus, και θα πρέπει να την βρούμε και να θέσουμε την μεταβλητή συστήματος $DBUS_SESSION_BUS_ADDRESS. Αλλά μπορεί το απομακρυσμένο σύστημα να τρέχει πολλές συνεδρίες χρήστη οπότε πρέπει να βρούμε την σωστή. Εδώ θα βρούμε ένα σκριπτάκι που βοηθά σε αυτό.

The Linux Registry;

Η registry των Windows ξεκίνησε σαν μια ταπεινή βάση για να βρίσκουν μεταξύ του η μια την άλλη οι εφαρμογές OLE. Αλλά σύντομα έγινε η βάση για τις ρυθμίσεις των Windows και για χρήστες (όταν απέκτησαν) αλλά και για το σύστημα. Και απλά είναι δύο κλήσεις συστήματος μια για εγγραφή και μια για ανάγνωση (δεν ξέρω αν έχει αλλάξει κάτι τα τελευταία χρόνια). Δεν έχει καμία δυνατότητα να βρεις τα κλειδιά, τι επιτρεπτές τιμές έχουν και τι κάνουν. Ούτε κάποια δυνατότητα για αυτόματη ενημέρωση αν αλλάζεις κάποια τιμή. Το GSettings δεν έχει αυτά τα προβλήματα.

Παρόμοια προβλήματα απαιτούν παρόμοιες λύσεις και δεν βλέπω κανένα κακό να δανείζεσαι και να βελτιώνεις ιδέες από άλλα λειτουργικά, όπως και αυτά με την σειρά τους να κάνουν το ίδιο με εσένα. Να το πω ωμά κρίνω και από το επίπεδο διείσδυσης κάθε λειτουργικού στην αγορά και δεν με απασχολεί καμία “ιδεολογική” καθαρότητα. Κρίνω μόνο αν κάτι κάνει καλά μια δουλεία ή όχι. Και το GSettings, τώρα που το γνωρίσαμε και λίγο καλύτερα είναι μια δυνατή τεχνολογία. Επίσης μου είναι αδιάφορο αν αποθηκεύει τις ρυθμίσεις σε δυαδικά αρχεία, σε αρχεία κειμένου η σε μια sqlite database.

Θα πρέπει να χρησιμοποιηθεί παντού; Σαφώς όχι, πχ δεν έχει κάποιο ιδιαίτερο νόημα σε εφαρμογές τερματικού. Μια υπηρεσία όπως η ssh ίσως να ωφελούνταν, θα ήταν ευκολότερο να αλλάξεις τις ρυθμίσεις με μια εντολή, αλλά εκεί προτιμώ την παλιά καλή μέθοδο που είναι φιλική και στο git. Για μια υπηρεσία σαν το apache σαφώς όχι. Αλλά για μια εφαρμογή desktop σίγουρα ΝΑΙ. Το κατάλληλο εργαλείο για την κατάλληλη δουλειά.

Ελπίζω με αυτό το κείμενο να σας έδωσα ιδέες και να φτιάξετε (όπως θα έλεγε και ο Bob Ross) πολλά μικρά χαρούμενα σκριπτάκια για τις καθημερινές σας ανάγκες. Και που ελπίζω να μοιραστείτε μια μέρα μαζί μας

7 «Μου αρέσει»

I’d just like to interject for a moment. What you’re referring to as Linux Registry, is in fact, GTK Registry.

Να συμπληρώσω απλά ότι η απάντηση στην ερώτηση «γιατί μακρυνάρια όπως το org.gnome.desktop.background picture-uri και όχι κάτι πιο εύκολο;» είναι ότι οι ρυθμίσεις αυτές δεν προορίζονταν ποτέ για να είναι user facing. Ο χρήστης θα είχε απλά ένα βολικό GUI όπου θα άλλαζε switches. Αλλά έχουμε ακόμα δρόμο στο UX του θέματος.

1 «Μου αρέσει»

Τεχνικά ορθότερο θα ήταν GLIB Registry, μιας και είναι σε ένα ποιο χαμηλό επίπεδο. Πολλές εφαρμογές χρησιμοποιούν το glib (ακόμα και αν χρησιμοποιούν το Qt) χωρίς να κάνουν καμία χρήση του gtk.

Η ομορφιά του συστήματος είναι πως υπάρχει μια αποσύζευξη (decοupling) μεταξύ των εφαρμογών και των ρυθμίσεων τους, και στους υπολογιστές μια καλή σχεδίαση θα πρέπει να έχει χαλαρές συνδέσεις μεταξύ των μερών της (σε αντίθεση με την μηχανολογία).

Κανένας λογικός άνθρωπος δεν θα αλλάξει μια ρύθμιση από το τερματικό αν υπάρχει γραφικός τρόπος, αλλά η αποσύζευξη σου επιτρέπει να έχεις και ξεχωριστά προγράμματα να κάνουν τις ρυθμίσεις. Αυτό κάνει εύκολο να έχεις τα διάφορα gnome-tweak-tools (το γιατί τα θέλεις στο gnome είναι μια άλλη ιστορία…).

Επίσης κάνει εύκολο να φτιάξεις εργαλεία που αλλιώς θα ήταν δύσκολο. Φαντάσου κάποιο πρόγραμμα που θα έπαιρνε την πρόγνωση του καιρού και θα άλλαζε ήχους συστήματος, εικονίδια, φόντο εργασίας. Ένα τέτοιο πρόγραμμα είναι δυνατό, αν και όχι κατ ανάγκην και χρήσιμο. Ιδανικά θα το έφτιαχνες με μια γλώσσα όπως η Python, που μπορεί να μιλήσει απευθείας με το GSettings, αλλά είναι εφικτό και με λίγες γραμμές σε Bash.

Χμμμ, τώρα που το σκέφτομαι, είναι μια ενδιαφέρουσα και σχετικά εύκολη προγραμματιστική πρόκληση για όποιος θέλει να το επιχειρήσει και να μας δείξει την λύση του :grin:

Ορθόν αλλά το gsettings, το dconf και διαδρομές όπως το /org/gnome/whatever δεν έχουν καμία λειτουργία σε περιβάλλον όπου δεν υπάρχει τίποτα GTK-based.

Αυτό που δε μπορώ να καταλάβω σε τέτοιες περιπτώσεις είναι το εξής: έφτιαξε κάποιος καλός άνθρωπος ένα GUI. Η σκέψη ότι το να δείχνει αυτό την ίδια πληροφορία με το τερματικό και όχι κάτι φιλικό προς τον χρήστη δεν πέρασε απ’ το μυαλό του; Θεωρώ ότι το Linux πάσχει σε αυτό το θέμα γενικότερα. Πολλά GUIs είναι εμφανώς afterthoughts ή φτιάχνονται «στο πόδι».

Για παράδειγμα, ο «απλός» χρήστης σίγουρα δε θα βρει νόημα στο «Schema org.gnome.desktop.background» αλλά θα καταλάβαινε εύκολα το «Αλλαγή φόντου επιφάνειας εργασίας». Αυτό όμως υπάρχει ήδη σε άλλο εργαλείο, συνεπώς ένα νέο GUI που περιλαμβάνει την ίδια λειτουργία και μάλιστα με non-user-friendly τρόπο είναι άχρηστο. Βέβαια, το GNOME δεν έχει και τρελή σχέση με το UX.