当前位置: 首页>>技术教程>>正文


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

, , , , ,

问题描述

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

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

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

我的问题是:

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

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

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

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

此外,strace -p pid -o output.txt命令会向文件中输入大量文本。

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

最佳解决思路

Do these GUI-based applications also execute the same command in the background?

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

为了给你一个如何使用库/模块的示例,请随时查看我的launcher list indicator.的源代码。我已经编写了一个函数来创建Gio.Settings类的实例,然后用它来修改Unity启动器取决于您希望在那里的列表类型。

How to have a peep at the internal working of these applications? I mean, is there any way of actually looking at the commands that are being executed at every click of button?

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

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

Do these applications open up a terminal in the background and execute these commands?

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

Addendum

  • 应用可以运行其他应用吗?是的,这是通过标准fork()execve()系统调用完成的。在Linux和其他* nix系统上创建进程的本质主要基于这两个。用于运行non-builtin命令的Shell机制特别使用了很多。当您以交互方式运行时

    $ ls 
    

    shell将通过fork()创建一个新进程,该进程将运行execve(),它将启动ls。因为execve()如何新的分叉过程将是lspipe()系统调用有助于回读ls的输出。我强烈建议阅读我对What is the difference between pipe and redirection的回答,以了解管道机制的工作原理 – 它不仅仅是|运算符,而且实际上是一个系统调用。

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

次佳解决思路

间谍发生的事情

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

dconf watch /

在一个终端。

gsettings

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

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

关于,gsettings,dconf和dconf数据库

gsettingsdconf的cli前端,后者编辑dconf数据库,其中大多数设置以二进制格式存储。另请参见this nice answer

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

command-line,unity,launcher,dconf,gsettings,ubuntu

工作样本

一个。在python中

command-line,unity,launcher,dconf,gsettings,ubuntu

为了向您展示在引擎盖下发生的事情,在工作样本下方,在单个(切换)按钮中切换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完成这项任务:

command-line,unity,launcher,dconf,gsettings,ubuntu

[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

  • 将其拖到启动器和right-click上

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

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/3092.html,未经允许,请勿转载。