it-swarm.com.de

Führen GUI-basierte Anwendungen Shell-Befehle im Hintergrund aus?

Ich bin erst vor 2 Tagen von Windows auf Ubuntu 16.04 umgestiegen. Mir gefällt, wie wir den Unity Desktop anpassen können. Ich spiele nur mit dem Erscheinungsbild der Desktop-Umgebung. Genau wie in Windows wollte ich, dass der Launcher am unteren Bildschirmrand angezeigt wird. Beim Googeln habe ich einen Befehl gefunden, der wie folgt lautet:

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

Es gibt auch das Unity-Tweak-Tool und den dconf-Editor, um den Job zu erledigen. Aber dies ist der GUI-Ansatz, um Dinge zu erledigen.

Meine Fragen sind:

  • Führen diese GUI-basierten Anwendungen denselben Befehl auch im Hintergrund aus?
  • Wie kann man einen Blick auf die interne Funktionsweise dieser Anwendungen werfen? Ich meine, gibt es eine Möglichkeit, die Befehle, die bei jedem Klick auf die Schaltfläche ausgeführt werden, tatsächlich anzuzeigen?
  • Öffnen diese Anwendungen ein Terminal im Hintergrund und führen diese Befehle aus?

Die Antwort hier gibt an, wie der Standard-Dateideskriptor des Prozesses abgerufen werden kann. Aber ich habe nichts in der Ausgabe bekommen.

Darüber hinaus wirft der Befehl strace -p pid -o output.txt eine große Menge Text in die Datei.

Kurz gesagt, funktioniert die Arbeit mit GUI-Anwendungen genauso wie die Arbeit über die Befehlszeile?

29
Logan

Führen diese GUI-basierten Anwendungen denselben Befehl auch im Hintergrund aus?

Ja und nein. Sie schreiben in die dconf -Datenbank der Einstellungen, können jedoch unterschiedliche Methoden verwenden. Programme, die in Python geschrieben wurden, werden wahrscheinlich das gi.repository.Gio -Modul verwenden (ich weiß, weil ich es oft benutze), oder sie können stattdessen gsettings als externen Befehl verwenden, indem sie subprocess.Popen(['gsettings','org.some.schema','some-key','value']) aufrufen, und es wird grundsätzlich als Shell-Befehl ausgeführt. Ein C-Programm wird etwas Ähnliches verwenden, wahrscheinlich eine gio.h -Bibliothek, oder es könnte sogar die exec() -Familie von Funktionen verwenden, um dasselbe zu tun wie Popen in Python. Um also Ihre Titelfrage zu beantworten: "Führen GUI-basierte Anwendungen Shell-Befehle im Hintergrund aus?" Sie können es, aber wahrscheinlich ist es nicht notwendig, weil es eine Bibliothek für jede Sprache gibt, in der die App geschrieben ist, und wahrscheinlich wird es ein bisschen schneller sein, eine Bibliotheksfunktion zu verwenden, als einen neuen Prozess zu erzeugen.

Um Ihnen ein Beispiel zu geben, wie es mit Bibliotheken/Modulen gemacht wird, werfen Sie einen Blick auf den Quellcode meines Launcher-Listen-Indikators. Dort bin ich haben eine Funktion geschrieben, um eine Instanz der Gio.Settings -Klasse zu erstellen und sie dann zu verwenden, um den Unity-Launcher abhängig von der Art der Liste zu ändern, die Sie dort haben möchten.

Wie kann man einen Blick auf die interne Funktionsweise dieser Anwendungen werfen? Ich meine, gibt es eine Möglichkeit, die Befehle, die bei jedem Klick auf die Schaltfläche ausgeführt werden, tatsächlich anzuzeigen?

Nein. Wenn Sie sehen möchten, welcher Befehl in der Programmiersprache dieser App ausgegeben wird, indem Sie eine Taste drücken oder auf Fensterelemente klicken, ist dies nicht möglich. Lesen Sie den Quellcode der Anwendung, wenn Sie ihn erhalten können. Sie können dconf watch / verwenden, um zu sehen, welche Einstellungen geändert werden, aber nicht, wie dies erfolgt.

Technisch gesehen können Sie, wenn Sie wissen, wie man einen Debugger bedient, Speicheradressen liest und eine Assemblersprache beherrscht, wissen, was eine App auf CPU- und Speicherebene tut. Dies wird als Software-Reverse-Engineering bezeichnet und wird häufig von Sicherheitsexperten verwendet, um schädliche Software zu analysieren und Schwachstellen in legitimer Software zu erkennen.

Öffnen diese Anwendungen ein Terminal im Hintergrund und führen diese Befehle aus?

Nein, es ist kein Terminal angeschlossen. Viele Programme wissen, wo sich die Datenbank dconf für den Benutzer befindet, und schreiben dort. Es gibt auch einen Interprozess-Kommunikationsbus namens dbus, über den Programme Signale senden können, und ein Programm wie "Hey, das ist eine Nachricht für mich!"

Nachtrag

  • Können Anwendungen andere Anwendungen ausführen? Ja, dies erfolgt über Standard-Systemaufrufe fork() und execve(). Das Wesentliche beim Erstellen von Prozessen unter Linux und anderen * nix-Systemen basiert weitgehend auf diesen beiden. Der Shell-Mechanismus zum Ausführen von nicht eingebauten Befehlen nutzt dies besonders häufig. Wenn Sie interaktiv laufen

    $ ls 
    

    die Shell erstellt über fork() einen neuen Prozess, der execve() ausführt und ls startet. Aufgrund dessen, wie execve() dieser neue gegabelte Prozess ls sein wird. Mit dem Systemaufruf pipe() können Sie die Ausgabe von ls zurücklesen. Ich empfehle dringend, meine Antwort für zu lesen. Worin besteht der Unterschied zwischen Pipe und Umleitung , um die Funktionsweise des Pipe-Mechanismus zu verstehen - es handelt sich nicht nur um den | -Operator, aber eigentlich ein syscall.

  • Können Anwendungen Shell-Befehle ausführen? Die Shell-Syntax wird nur von Shell selbst verstanden. Sie können jedoch eine Shell mit einem Befehlszeilenschalter -c starten und entsprechende Befehle bereitstellen. Dies wird häufig für benutzerdefinierte Verknüpfungen verwendet, die in GNOME oder anderen Desktop-Umgebungen festgelegt wurden, da benutzerdefinierte Verknüpfungen auf ausführbaren Dateien ausgeführt werden und es keine Shell gibt, die die Syntax versteht. Als Beispiel würden Sie bash -c 'xdotool key Ctrl+Alt+T' ausführen, um indirekt den Befehl xdotool auszuführen, oder bash -c 'cd $HOME/Desktop; touch New_File', um eine neue Datei über eine Verknüpfung auf dem Desktop zu erstellen. Dies ist ein besonders interessantes Beispiel, da Sie eine Shell-Variable verwenden können, da Sie eine Shell explizit verwenden.

35

Ausspionieren, was passiert

Die meisten Funktionen dieser Einstellungseditoren können durch Ausführen von überwacht werden

dconf watch /

in einem Terminal.

gEinstellungen

In den meisten Fällen müssen diese Anwendungen die dconf -Datenbank (weiter unten) bearbeiten, um das zu erreichen, was Sie mit dem obigen Befehl sehen. Dies kann entweder direkt erfolgen, indem die cli-Optionen von dconf (was nicht bevorzugt ist) verwendet werden, oder indem das ausgeführt wird entsprechende gsettings Befehle, wie der, den Sie erwähnen.

Zum Ausführen dieser Befehle wird kein Terminalfenster benötigt, wie Sie in den Beispielen sehen können.

About, gsettings, dconf und die Datenbank dconf

gsettings ist das Cli-Frontend für dconf, das seinerseits die Datenbank dconf bearbeitet, in der die meisten Einstellungen im Binärformat gespeichert sind. Siehe auch diese nette Antwort .

Die Datenbank dconf kann übrigens auch über die grafische Benutzeroberfläche mit dem Editor dconf bearbeitet werden, der sich in den Repositorys befindet:

enter image description here

Arbeitsproben

ein. In Python

enter image description here

Um Ihnen zu zeigen, was unter der Haube passiert, klicken Sie unterhalb eines Arbeitsbeispiels auf eine einzelne Schaltfläche, um Ihre Startposition von der GUI aus umzuschalten:

#!/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()
  • Füge den Code in einen leeren file.py ein
  • starte es mit dem Befehl:

    python3 /path/to/file.py
    

...und Spaß haben.

b. Startsymbol

Sogar ein einfacher Launcher kann die Aufgabe über die GUI erledigen:

enter image description here

[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
  • Füge den Code in eine leere Datei ein und speichere ihn als setlauncher.desktop
  • Ziehen Sie es auf den Launcher und klicken Sie mit der rechten Maustaste

Speichern Sie es für den dauerhaften Gebrauch in ~/.local/share/applications (für den lokalen Gebrauch) oder ~/usr/share/applications für alle Benutzer.

21
Jacob Vlijm