基于GUI的应用程序是否在后台执行shell命令?

我在2天前从Windows迁移到Ubuntu 16.04。 我喜欢我们自定义Unity桌面的方式。 我正在玩桌面环境的外观和感觉。 就像在Windows中一样,我希望启动器位于屏幕的底部。 在谷歌上,我找到了一个命令,如下所示:

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

此外,还有unity-tweak-tool和dconf编辑器来完成工作。 但这些是完成工作的GUI方法。

我的问题是:

  • 这些基于GUI的应用程序是否也在后台执行相同的命令?
  • 如何窥探这些应用程序的内部工作? 我的意思是,有没有办法真正查看每次点击按钮时执行的命令?
  • 这些应用程序是否在后台打开终端并执行这些命令?

这里的答案讲述了如何获取进程的标准文件描述符。 但是,我在输出中没有得到任何东西。

而且, strace -p pid -o output.txt命令会向文件中抛出大量文本。

那么,简而言之,使用GUI应用程序做的事情与从命令行做事情一样吗?

这些基于GUI的应用程序是否也在后台执行相同的命令?

是的,不是。 他们写入设置的dconf数据库,但他们可能使用不同的方法来执行此操作。 用Python编写的程序可能会使用gi.repository.Gio模块(我知道因为我gi.repository.Gio使用它),或者他们可以通过调用subprocess.Popen(['gsettings','org.some.schema','some-key','value'])来使用gsettings作为外部命令subprocess.Popen(['gsettings','org.some.schema','some-key','value']) ,它基本上作为shell命令运行。 AC程序将使用类似的东西,可能是gio.h库,或者它甚至可以使用exec()函数系列来执行与Popen在python中相同的操作。 所以回答你的标题问题:“基于GUI的应用程序在后台执行shell命令吗?” 他们可以,但可能没有必要,因为有一个库可以用于编写应用程序的任何语言,并且使用库函数可能会比生成新进程快一些。

为了让您了解如何使用库/模块完成它,请随时查看我的启动器列表指示器的源代码。 在那里,我编写了一个函数来创建Gio.Settings类的实例,然后根据您想要的列表类型使用它来修改Unity启动器。

如何窥探这些应用程序的内部工作? 我的意思是,有没有办法真正查看每次点击按钮时执行的命令?

不可以。如果您想在按下按钮或单击窗口元素时查看该应用程序编程语言中发出的命令,则无法进行。 如果可以获得它,请阅读应用程序的源代码。 您可以使用dconf watch /查看正在更改的设置,但不知道它是如何完成的。

从技术上讲,如果您知道如何操作调试器,读取内存地址以及了解某些汇编语言,那么您就可以知道应用程序在CPU和内存级别上的作用。 这称为软件逆向工程,安全专业人员经常使用它来分析恶意软件并发现合法软件中的漏洞。

这些应用程序是否在后台打开终端并执行这些命令?

不,没有附加终端。 许多程序知道用户的dconf数据库所在的位置并在那里写入。 还有一个称为dbus的进程间通信总线,程序可以发送信号,程序就像“嘿,这对我来说是个消息!”

窥探发生的事情

这些设置编辑器的大部分内容都可以通过运行来观察

 dconf watch / 

在一个终端。

gsettings

大多数情况下,为了实现您在上面的命令中看到的情况,这些应用程序将需要编辑dconf数据库(下面进一步说明)。 这可以通过使用dconf的cli选项(不是首选) 直接完成,也可以通过运行相应的gsettings命令来完成,就像你提到的那样。

要运行这些命令,不需要终端窗口,如示例中所示。

关于,gsettings,dconf和dconf数据库

gsettingsgsettings的cli前端,它反过来以二进制格式编辑dconf数据库,其中存储了大多数设置。 另见这个好答案 。

顺便说一下, dconf数据库也可以通过dconf编辑器从GUI编辑,该编辑器位于存储库中:

在此处输入图像描述

工作样本

一个。 在python中

在此处输入图像描述

为了向您展示在引擎盖下发生的事情,在工作样本下方,在单个(切换)按钮中切换GUI的启动器位置:

 #!/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() 
  • 将代码粘贴到空的file.py
  • 通过命令运行它:

     python3 /path/to/file.py 

…玩得开心。

湾 启动器图标

即使是一个简单的启动器也可以从GUI完成这项任务:

在此处输入图像描述

 [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 
  • 将代码粘贴到空文件中,将其另存为setlauncher.desktop
  • 将其拖到启动器上并单击鼠标右键

要永久使用,请将其存储在~/.local/share/applications (供本地使用)或~/usr/share/applications以供所有用户使用。