Les applications basées sur une interface graphique exécutent-elles des commandes shell en arrière-plan?


29

J'ai migré vers Ubuntu 16.04 il y a seulement 2 jours à partir de Windows. J'aime la façon dont nous pouvons personnaliser le bureau Unity. Je ne fais que jouer avec l'apparence de l'environnement de bureau. Tout comme sous Windows, je voulais que le lanceur soit en bas de l'écran. Sur Google, j'ai trouvé une commande qui va comme:

gsettings set com.canonical.Unity.Launcher launcher-position Bottom

En outre, il y a l'outil unitaire-tweak-tool et l'éditeur dconf pour faire le travail. Mais ce sont l'approche GUI pour faire avancer les choses.

Mes questions sont:

  • Ces applications basées sur l'interface graphique exécutent-elles également la même commande en arrière-plan?
  • Comment avoir un aperçu du fonctionnement interne de ces applications? Je veux dire, y a-t-il un moyen de regarder réellement les commandes qui sont exécutées à chaque clic de bouton?
  • Ces applications ouvrent-elles un terminal en arrière-plan et exécutent-elles ces commandes?

La réponse ici indique comment obtenir le descripteur de fichier standard du processus. Mais, je n'ai rien obtenu dans la sortie.

De plus, la strace -p pid -o output.txtcommande jette une énorme quantité de texte dans le fichier.

Donc, en bref, est-ce que faire les choses en utilisant des applications GUI revient à faire des choses à partir de la ligne de commande?

Réponses:


35

Ces applications basées sur l'interface graphique exécutent-elles également la même commande en arrière-plan?

Oui et non. Ils écrivent dans la dconfbase de données des paramètres, mais ils peuvent utiliser différentes méthodes pour le faire. Les programmes écrits en Python utiliseront probablement le gi.repository.Giomodule (je le sais parce que je l'utilise beaucoup) ou ils peuvent utiliser à la place gsettingscomme commande externe en appelant subprocess.Popen(['gsettings','org.some.schema','some-key','value']), et il fonctionnera essentiellement comme une commande shell. Le programme AC utilisera quelque chose de similaire, probablement une gio.hbibliothèque, ou il pourrait même utiliser la exec()famille de fonctions pour faire la même chose qu'en Popenpython. Donc, pour répondre à votre question de titre: "Les applications basées sur l'interface graphique exécutent-elles des commandes shell en arrière-plan?" Ils le peuvent, mais ce n'est probablement pas nécessaire car il existe une bibliothèque pour la langue dans laquelle l'application est écrite, et il sera probablement un peu plus rapide d'utiliser une fonction de bibliothèque que de générer un nouveau processus.

Pour vous donner un exemple de la façon dont cela est fait avec les bibliothèques / modules, n'hésitez pas à jeter un œil au code source de mon indicateur de liste de lanceurs. Là, j'ai écrit une fonction pour créer une instance de la Gio.Settingsclasse, puis l'utiliser pour modifier le lanceur Unity en fonction du type de liste que vous souhaitez y avoir.

Comment avoir un aperçu du fonctionnement interne de ces applications? Je veux dire, existe-t-il un moyen de regarder les commandes qui sont exécutées à chaque clic de bouton?

Non. Si vous voulez voir quelle commande est émise dans le langage de programmation de cette application lorsque vous appuyez sur un bouton ou cliquez sur des éléments de fenêtre, ce n'est pas possible. Lisez le code source de l'application, s'il est possible de l'obtenir. Vous pouvez utiliser dconf watch /pour voir quels paramètres sont modifiés, mais pas comment cela se fait.

Techniquement, si vous savez utiliser un débogueur, lire des adresses mémoire et connaître un langage d'assemblage, vous pouvez savoir ce qu'une application fait au niveau du processeur et de la mémoire. Ceci est connu sous le nom d'ingénierie inverse des logiciels et est fréquemment utilisé par les professionnels de la sécurité pour analyser les logiciels malveillants et découvrir les vulnérabilités des logiciels légitimes.

Ces applications ouvrent-elles un terminal en arrière-plan et exécutent-elles ces commandes?

Non, aucun terminal n'est connecté. De nombreux programmes savent où se trouve la dconfbase de données de l'utilisateur et y écrivent. Il y a aussi un bus de communication inter-processus appelé dbus, où les programmes peuvent envoyer des signaux, et un programme sera comme "Hé, c'est un message pour moi!"

Addenda

  • Les applications peuvent-elles exécuter d'autres applications? Oui, cela se fait via des appels standard fork()et execve()système. L'essence de la création de processus sur Linux et d'autres systèmes * nix est largement basée sur ces deux. Le mécanisme shell pour exécuter des commandes non intégrées en utilise beaucoup en particulier. Lorsque vous exécutez de manière interactive

    $ ls 
    

    le shell créera un nouveau processus via fork(), ce processus s'exécutera execve() et démarrera ls. En raison de la façon dont execve()ce nouveau processus bifurqué sera ls. L' pipe()appel système est ce qui aidera à relire la sortie de ls. Je suggère fortement de lire ma réponse pour Quelle est la différence entre le tuyau et la redirection pour comprendre comment fonctionne le mécanisme du tuyau - ce n'est pas seulement l' |opérateur, mais en fait un appel système.

  • Les applications peuvent-elles exécuter des commandes shell? Non. La syntaxe du shell n'est comprise que par le shell lui-même. Cependant, vous pouvez démarrer un shell avec un -ccommutateur de ligne de commande et fournir des commandes appropriées. Ceci est souvent utilisé pour les raccourcis personnalisés définis dans GNOME ou d'autres environnements de bureau, car les raccourcis personnalisés fonctionnent sur les exécutables et il n'y a pas de shell pour comprendre la syntaxe. Ainsi, par exemple, vous feriez bash -c 'xdotool key Ctrl+Alt+T'pour exécuter indirectement la xdotoolcommande ou bash -c 'cd $HOME/Desktop; touch New_File'pour créer un nouveau fichier sur le bureau via un raccourci. C'est un exemple particulièrement intéressant car vous pouvez utiliser une variable shell, car vous utilisez explicitement un shell.


2
Merci beaucoup @Serg pour l'explication détaillée et la réponse à chaque question séparément et systématiquement!
ptmdevncoder

@Logan mon plaisir, toujours heureux d'aider :)
Sergiy Kolodyazhnyy

1
Heureusement, la source des outils mentionnés est disponible car ils sont FLOSS. Par conséquent, je dirais que les inverser est un peu exagéré dans ce cas. :)
Andrea Lazzarotto

1
@AndreaLazzarotto Yep, Unity Tweak Tool et Dconf editor - ceux-ci sont open source, il n'est donc pas nécessaire de les désosser. Dans ma réponse, j'ai gardé tout très général et j'ai essayé de couvrir non seulement ces outils, mais d'autres possibilités
Sergiy Kolodyazhnyy

Plus rapide est rarement le point pour les applications GUI. Échapper ou rassembler les valeurs à utiliser avec un outil shell est fastidieux, facile à se tromper et inutile si vous pouvez simplement utiliser la bibliothèque. Re débogage: si l'application est installée avec des symboles de débogage et écrite dans un langage supporté par gdb (sur debian par exemple en installant un paquet -dbg correspondant), vous n'avez pas besoin de connaître l'assembleur: gdb vous montrera le code source en utilisant le informations de débogage pendant que vous parcourez l'application. Ce qui sera plus difficile, c'est de trouver un point d'entrée approprié pour commencer le débogage, en raison de l'ennuyeux GUI plate-forme.
Jonas Schäfer du

21

Espionner ce qui se passe

La plupart de ce que font ces éditeurs de paramètres peut être regardé en exécutant

dconf watch /

dans un terminal.

gsettings

De plus, la plupart du temps, pour réaliser ce que vous voyez se produire avec la commande ci-dessus, ces applications devront modifier la dconfbase de données (plus loin ci-dessous). Cela peut être fait soit directement , en utilisant les options cli de dconf (ce qui n'est pas préféré), soit en exécutant les gsettingscommandes correspondantes , comme celle que vous mentionnez.

Pour exécuter ces commandes, aucune fenêtre de terminal n'est nécessaire, comme vous pouvez le voir dans les exemples.

À propos, gsettings, dconf et la base de données dconf

gsettingsest l'interface client de cli dconf, qui à son tour édite la dconfbase de données, où la plupart des paramètres sont stockés, au format binaire. Voir aussi cette belle réponse .

La dconfbase de données, en passant, peut également être édité à partir de l'interface graphique par l' dconféditeur, qui est dans les dépôts:

entrez la description de l'image ici

Échantillons de travail

une. En python

entrez la description de l'image ici

Pour vous montrer ce qui se passe sous le capot, ci-dessous un échantillon de travail pour basculer votre position du lanceur de l'interface graphique dans un seul bouton (bascule):

#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import subprocess

key = ["com.canonical.Unity.Launcher", "launcher-position"]

class ToggleWin(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Toggle")
        button = Gtk.Button("Toggle launcherposition")
        button.connect("clicked", self.toggle)
        self.add(button)

    def toggle(self, *args):
        # read the current setting on launcher position
        current = subprocess.check_output([
            "gsettings", "get", key[0], key[1]
            ]).decode("utf-8").strip()
        # toggle to the other option
        new = "'Left'" if current == "'Bottom'" else "'Bottom'"
        subprocess.Popen([
            "gsettings", "set", key[0], key[1], new
            ])

def delete_actions(*args):
    Gtk.main_quit()

def miniwindow():
    window = ToggleWin()
    window.connect("destroy", delete_actions)
    window.show_all()
    Gtk.main()

miniwindow()
  • Collez le code dans un espace vide file.py
  • exécutez-le par la commande:

    python3 /path/to/file.py
    

...et amusez-vous.

b. Icône de lanceur

Même un simple lanceur peut faire le travail à partir de l'interface graphique:

entrez la description de l'image ici

[Desktop Entry]
Name=Set launcherposition
Exec=zenity --info --text="Right- click to set launcher position"
Type=Application
StartupNotify=False
Icon=preferences-system

Actions=Launcher to bottom;Launcher on the left;

[Desktop Action Launcher to bottom]
Name=Launcher to bottom
# right click option to set launcher to bottom
Exec=gsettings set com.canonical.Unity.Launcher launcher-position Bottom

[Desktop Action Launcher on the left]
Name=Launcher on the left
# right click option to set launcher to left
Exec=gsettings set com.canonical.Unity.Launcher launcher-position Left
  • Collez le code dans un fichier vide, enregistrez-le sous setlauncher.desktop
  • Faites-le glisser sur le lanceur et faites un clic droit

Pour une utilisation permanente, stockez-le ~/.local/share/applications(pour une utilisation locale) ou ~/usr/share/applicationspour tous les utilisateurs.


@Logan ne le mentionne pas :)
Jacob Vlijm
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.