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


29

我仅在两天前从Windows迁移到Ubuntu 16.04。我喜欢我们自定义Unity桌面的方式。我只是在玩弄桌面环境的外观。就像在Windows中一样,我希望启动器位于屏幕底部。在Googling上,我发现了一条类似于以下命令:

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

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

我的问题是:

  • 这些基于GUI的应用程序还会在后台执行相同的命令吗?
  • 如何窥视这些应用程序的内部工作?我的意思是,有没有一种方法可以真正查看每次单击按钮时正在执行的命令?
  • 这些应用程序是否在后台打开终端并执行这些命令?

这里的答案告诉您如何获取进程的标准文件描述符。但是,我在输出中什么都没有。

此外,该strace -p pid -o output.txt命令将大量文本抛出到文件中。

简而言之,使用GUI应用程序进行的操作是否与通过命令行进行操作相同?

Answers:


35

这些基于GUI的应用程序还会在后台执行相同的命令吗?

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

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

如何窥视这些应用程序的内部工作?我的意思是,有没有一种方法可以真正查看每次单击按钮时正在执行的命令?

否。如果您想在按下按钮或单击窗口元素时查看使用该应用程序的编程语言发出的命令,则不可能。如果有可能,请阅读应用程序的源代码。您可以dconf watch /用来查看正在更改的设置,但不能查看更改的方式。

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

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

不,没有连接终端。许多程序都知道dconf用户数据库的位置,然后在此处写入。还有一个称为的进程间通信总线dbus,程序可以在该总线上发送信号,并且程序将类似于“嘿,这是给我的消息!”

附录

  • 应用程序可以运行其他应用程序吗?是的,这是通过标准fork()execve()系统调用完成的。在Linux和其他* nix系统上创建进程的本质很大程度上基于这两个。运行非内置命令的Shell机制使用了很多。交互式运行时

    $ ls 
    

    外壳将通过创建一个新的进程fork(),该进程execve() 将开始运行ls。因为execve()新的分叉过程将是这样ls。该pipe()系统调用是什么将帮助回读的输出ls。我强烈建议阅读我关于管道和重定向之间的区别的答案,以了解管道机制的工作原理-它不仅是|运算符,而且实际上是系统调用。

  • 应用程序可以运行shell命令吗?不可以。Shell语法只能由Shell本身理解。但是,您可以做的是使用命令行-c开关启动shell 并提供适当的命令。这通常用于在GNOME或其他桌面环境中设置的自定义快捷方式,因为自定义快捷方式可在可执行文件上运行,并且没有外壳可用于理解语法。因此,作为示例,您bash -c 'xdotool key Ctrl+Alt+T'可以间接运行xdotool命令或bash -c 'cd $HOME/Desktop; touch New_File'通过快捷方式在桌面上创建新文件。这是一个非常有趣的示例,因为可以显式地使用shell,因此可以使用shell变量。


2
非常感谢@Serg的详细解释,并分别系统地回答每个问题!
ptmdevncoder

@Logan我很高兴,总是很乐意为您提供帮助:)
Sergiy Kolodyazhnyy

1
幸运的是,由于这些工具是FLOSS,因此可以找到这些工具的来源。因此,在这种情况下,我想说将它们反转是有点矫kill过正。:)
Andrea Lazzarotto

1
@AndreaLazzarotto是的,Unity Tweak工具和Dconf编辑器-这些都是开源的,因此无需对它们进行反向工程。在我的回答中,我将所有内容都保留得很笼统,并尝试不仅涵盖那些工具,还涵盖其他可能性
Sergiy Kolodyazhnyy

对于GUI应用程序而言,更快很少是要点。转义或编组供Shell工具使用的值是乏味的,如果您可以简单地使用库,则容易出错且毫无意义。重新调试:如果应用程序安装了调试符号,并且以gdb支持的语言编写(例如在debian上,例如通过安装相应的-dbg软件包),则您无需了解汇编程序:gdb将使用逐步调试应用程序时调试信息。由于无聊的GUI样板操作,因此很难找到合适的入口点来开始进行调试。
乔纳斯·谢弗

21

监视发生的事情

这些设置编辑器的大多数操作都可以通过运行查看

dconf watch /

在一个终端。

设置

同样,在大多数情况下,要实现上面命令所显示的功能,这些应用程序将需要编辑dconf数据库(在下文中)。这可以通过使用dconf的cli选项(不推荐使用)直接运行,也可以通过运行相应的命令(如您提到的命令)直接完成。gsettings

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

关于,gsettings,dconf和dconf数据库

gsettings是的cli前端dconf,它依次dconf以二进制格式编辑存储大多数设置的数据库。另请参见这个不错的答案

dconf数据库,顺便说一下,也可以从由GUI编辑dconf编辑器,它是在存储库中:

在此处输入图片说明

工作样本

一种。在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
    

...玩得开心。

b。启动器图标

即使是简单的启动器也可以通过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供所有用户使用。


@Logan别提了:)
Jacob Vlijm '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.