GUIベースのアプリケーションはバックグラウンドでシェルコマンドを実行しますか?


29

Windowsから2日前に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アプリケーションを使用して物事を行うのは、コマンドラインから何かをするのと同じですか?

回答:


35

これらのGUIベースのアプリケーションもバックグラウンドで同じコマンドを実行しますか?

はいといいえ。それらdconfは設定のデータベースに書き込みますが、異なる方法を使用して書き込むことができます。Pythonで書かれたプログラムはおそらくgi.repository.Gioモジュールを使用するでしょう(私はそれを頻繁に使用するので知っています)か、代わりにgsettingsを呼び出すことsubprocess.Popen(['gsettings','org.some.schema','some-key','value'])で外部コマンドとして使用でき、基本的にシェルコマンドとして実行されます。ACプログラムは類似の何か、おそらくgio.hライブラリーを使用します。あるいは、Pythonの場合exec()と同じように関数ファミリーを使用することもできPopenます。タイトルの質問に答えるには、「GUIベースのアプリケーションはバックグラウンドでシェルコマンドを実行しますか?」可能ですが、アプリが記述されている言語に対応したライブラリがあるため、おそらく必要ありません。おそらく、新しいプロセスを生成するよりも、ライブラリ関数を使用する方が少し速くなるでしょう。

ライブラリ/モジュールでどのように行われるかのサンプルを提供するには、ランチャーリストインジケーターのソースコードをご覧ください。そこで、Gio.Settingsクラスのインスタンスを作成し、それを使用して、そこに保持したいリストのタイプに応じてUnityランチャーを変更する関数を作成しました。

これらのアプリケーションの内部動作をのぞき見する方法は?つまり、ボタンをクリックするたびに実行されているコマンドを実際に見る方法はありますか?

いいえ。ボタンを押したり、ウィンドウ要素をクリックしたときに、そのアプリのプログラミング言語で発行されたコマンドを確認したい場合、それは不可能です。入手できる場合は、アプリケーションのソースコードを読みます。dconf watch /どの設定が変更されているかを確認できますが、変更方法は確認できません。

技術的には、デバッガの操作方法、メモリアドレスの読み取り方法、およびアセンブリ言語の知識があれば、アプリがCPUおよびメモリレベルで何をするかを知ることができます。これはソフトウェアリバースエンジニアリングとして知られており、悪意のあるソフトウェアを分析し、正当なソフトウェアの脆弱性を発見するためにセキュリティの専門家によって頻繁に使用されます。

これらのアプリケーションはバックグラウンドでターミナルを開き、これらのコマンドを実行しますか?

いいえ、端末は接続されていません。多くのプログラムdconfは、ユーザーのデータベースがどこにあるかを知っており、そこに書き込みます。またdbus、プログラムとして信号を送信できるプロセス間通信バスもあり、プログラムは「やあ、それは私のメッセージだ!」

補遺

  • アプリケーションは他のアプリケーションを実行できますか?はい、それは標準を介して行われますfork()し、execve()システムコールの。Linuxおよび他の* nixシステムでプロセスを作成する本質は、主にこれら2つに基づいています。非組み込みコマンドを実行するためのシェルメカニズムは、特にそれを多く使用します。インタラクティブに実行するとき

    $ ls 
    

    シェルは経由fork()で新しいプロセスを作成し、そのプロセスexecve() は起動し実行されますlsexecve()その新しいフォークされたプロセスがどうなるかのためlspipe()システムコールは、の出力をリードバックに役立つものですlsパイプとリダイレクションの違いについての答えを読んでパイプメカニズムのしくみを理解することを強くお勧め|します。これは単なる演算子ではなく、実際にはシステムコールです。

  • アプリケーションはシェルコマンドを実行できますか?いいえ。シェル構文はシェル自体によってのみ理解されます。ただし、できることは、コマンドライン-cスイッチでシェルを起動し、適切なコマンドを提供することです。カスタムショートカットは実行可能ファイルで動作し、構文を理解するシェルがないため、これはGNOMEまたは他のデスクトップ環境で設定されたカスタムショートカットによく使用されます。したがって、例として、bash -c 'xdotool key Ctrl+Alt+T'間接的にxdotoolコマンドを実行するかbash -c 'cd $HOME/Desktop; touch New_File'、ショートカットを使用してデスクトップに新しいファイルを作成します。シェルを明示的に使用しているため、シェル変数を使用できるため、これは特に興味深い例です。


2
詳細な説明と各質問に個別に体系的に回答してくれた@Sergに感謝します!
ptmdevncoder

@Logan私の喜び、いつも助けてくれてうれしい:)
セルギーKolodyazhnyy

1
幸いなことに、言及されたツールのソースはFLOSSであるため利用可能です。したがって、この場合、それらを逆にするのは少しやり過ぎだと思います。:)
アンドレアラザロット

1
@AndreaLazzarotto Yep、Unity Tweak Tool、およびDconfエディター-これらはオープンソースなので、これらをリバースエンジニアリングする必要はありません。私の答えでは、すべてを非常に一般的なものにし、それらのツールだけでなく、他の可能性もカバーしようとしました
Sergiy Kolodyazhnyy

GUIアプリケーションの場合、高速化はめったにありません。シェルツールで使用するために値をエスケープまたはマーシャリングするのは退屈で、間違えやすく、ライブラリを単純に使用できれば無意味です。再デバッグ:アプリケーションがデバッグシンボルを使用してインストールされ、gdbがサポートする言語で記述されている場合(たとえば、対応する-dbgパッケージをインストールすることにより)、アセンブラーを知る必要はありません:gdbは、アプリケーションをステップ実行する際のデバッグ情報。難しいのは、退屈なGUIボイラープレートのために、デバッグを開始する適切なエントリポイントを見つけることです。
ジョナスシェーファー

21

何が起こるかをスパイ

これらの設定エディターが行うことのほとんどは、実行することで見ることができます

dconf watch /

ターミナルで。

gsettings

また、ほとんどの場合、上記のコマンドで発生していることを確認するには、これらのアプリケーションでdconfデータベースを編集する必要があります(以下を参照)。これは、dconfのcliオプション(推奨されません)を使用するか、または言及したような対応するコマンドを実行することにより、直接行うことができます。gsettings

これらのコマンドを実行するには、例でわかるように、ターミナルウィンドウは必要ありません。

gsettings、dconf、dconfデータベースについて

gsettingsは、CLIのフロントエンドであり、ほとんどの設定が保存されてdconfいるdconfデータベースをバイナリ形式で編集します。この素敵な答えもご覧ください。

dconfデータベースは、方法によって、またにより、GUIから編集することができdconfリポジトリにあるエディタ:

ここに画像の説明を入力してください

作業サンプル

a。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 :)
ジェイコブVlijm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.