web-dev-qa-db-ja.com

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

Windowsから2日前にUbuntu 16.04に移行しました。 Unityデスクトップをカスタマイズする方法が気に入っています。デスクトップ環境のルックアンドフィールで遊んでいます。 Windowsの場合と同じように、ランチャーを画面の下部に配置したかったのです。グーグルで、次のようなコマンドを見つけました:

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

また、作業を完了するためのunity-Tweak-toolとdconfエディターがあります。しかし、これらは物事を成し遂げるためのGUIアプローチです。

私の質問は:

  • これらのGUIベースのアプリケーションもバックグラウンドで同じコマンドを実行しますか?
  • これらのアプリケーションの内部動作をのぞき見する方法は?つまり、ボタンをクリックするたびに実行されているコマンドを実際に見る方法はありますか?
  • これらのアプリケーションはバックグラウンドでターミナルを開き、これらのコマンドを実行しますか?

答え here は、プロセスの標準ファイル記述子を取得する方法を示します。しかし、出力には何も表示されませんでした。

さらに、strace -p pid -o output.txtコマンドは、大量のテキストをファイルにスローします。

つまり、要するに、GUIアプリケーションを使用して何かを行うことは、コマンドラインから何かを行うことと同じですか

29
Logan

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

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

ライブラリ/モジュールでどのように行われるかのサンプルを提供するために、私の launcher list indicator。 のソースコードを見てください。Gio.Settingsのインスタンスを作成する関数を書きました。クラスを作成してから、使用するリストの種類に応じてUnityランチャーを変更します。

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

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

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

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

いいえ、端末は接続されていません。多くのプログラムは、ユーザーのdconfデータベースの場所を認識し、そこに書き込みます。 dbusとして知られるプロセス間通信バスもあり、プログラムは信号を送信できます。プログラムは「ねえ、それは私のメッセージです!」のようになります。

補遺

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

    $ ls 
    

    シェルはfork()を介して新しいプロセスを作成し、そのプロセスはexecve()を実行し、lsを開始します。そのため、execve()その新しいフォークされたプロセスはlsになります。 pipe()システムコールは、lsの出力を読み返すのに役立ちます。 パイプとリダイレクトの違い の答えを読んでパイプメカニズムの仕組みを理解することを強くお勧めします-それは|演算子だけでなく、実際にはsyscallです。

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

35

何が起こるかをスパイ

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

dconf watch /

ターミナルで。

gsettings

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

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

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

gsettingsdconfのc​​liフロントエンドであり、ほとんどの設定がバイナリ形式で保存されているdconfデータベースを順番に編集します。 this nice answer も参照してください。

ちなみに、dconfdatabaseは、リポジトリにあるdconfエディターによってGUIから編集することもできます。

enter image description here

作業サンプル

a。 Pythonで

enter image description here

ボンネットの下で何が起こるかを示すために、作業サンプルの下で、単一の(トグル)ボタンで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からジョブを実行できます。

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
  • コードを空のファイルに貼り付け、setlauncher.desktopとして保存します
  • ランチャーにドラッグして右クリックします

永続的に使用する場合は、~/.local/share/applications(ローカル使用)またはすべてのユーザーの~/usr/share/applicationsに保存します。

21
Jacob Vlijm