Apakah aplikasi berbasis GUI menjalankan perintah shell di latar belakang?

29

Saya telah bermigrasi ke Ubuntu 16.04 hanya 2 hari yang lalu dari Windows. Saya suka cara kami dapat menyesuaikan Desktop Persatuan. Saya hanya bermain-main dengan tampilan dan nuansa lingkungan Desktop. Sama seperti di Windows, saya ingin peluncur berada di bagian bawah layar. Di Googling, saya menemukan perintah yang berbunyi seperti:

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

Juga, ada unity-tweak-tool dan dconf editor untuk menyelesaikan pekerjaan. Tapi ini adalah pendekatan GUI untuk menyelesaikan sesuatu.

Pertanyaan saya adalah:

  • Apakah aplikasi berbasis GUI ini juga menjalankan perintah yang sama di latar belakang?
  • Bagaimana cara mengintip kerja internal aplikasi ini? Maksud saya, apakah ada cara untuk benar-benar melihat perintah yang dieksekusi pada setiap klik tombol?
  • Apakah aplikasi ini membuka terminal di latar belakang dan menjalankan perintah ini?

Jawabannya di sini memberi tahu cara mendapatkan deskriptor file standar proses. Tapi, saya tidak mendapatkan apa-apa di output.

Selain itu, strace -p pid -o output.txtperintah tersebut membuang sejumlah besar teks ke dalam file.

Jadi, singkatnya, apakah melakukan hal-hal menggunakan aplikasi GUI sama dengan melakukan hal-hal dari commandline?

ptmdevncoder
sumber

Jawaban:

35

Apakah aplikasi berbasis GUI ini juga menjalankan perintah yang sama di latar belakang?

Iya dan tidak. Mereka menulis ke dconfdatabase pengaturan, tetapi mereka bisa menggunakan cara yang berbeda untuk melakukannya. Program yang ditulis dengan Python kemungkinan akan menggunakan gi.repository.Giomodul (saya tahu karena saya sering menggunakannya) atau mereka dapat menggunakan gsettingssebagai perintah eksternal dengan memanggil subprocess.Popen(['gsettings','org.some.schema','some-key','value']), dan pada dasarnya akan berjalan sebagai perintah shell. Program AC akan menggunakan sesuatu yang mirip, mungkin gio.hperpustakaan, atau bahkan bisa menggunakan exec()keluarga fungsi untuk melakukan hal yang sama seperti Popenpada python. Jadi untuk menjawab pertanyaan judul Anda: "Apakah aplikasi berbasis GUI menjalankan perintah shell di latar belakang?" Mereka bisa, tetapi kemungkinan itu tidak perlu karena ada perpustakaan untuk bahasa apa pun yang ditulis aplikasi, dan kemungkinan itu akan menjadi sedikit lebih cepat untuk menggunakan fungsi perpustakaan, daripada menelurkan proses baru.

Untuk memberi Anda contoh bagaimana hal ini dilakukan dengan perpustakaan / modul, jangan ragu untuk melihat kode sumber indikator daftar peluncur saya . Di sana saya telah menulis sebuah fungsi untuk membuat turunan Gio.Settingskelas dan kemudian menggunakannya untuk memodifikasi peluncur Persatuan tergantung pada jenis daftar yang ingin Anda miliki di sana.

Bagaimana cara mengintip kerja internal aplikasi ini? Maksud saya, apakah ada cara untuk benar-benar melihat perintah yang dieksekusi pada setiap klik tombol?

Tidak. Jika Anda ingin melihat perintah mana yang dikeluarkan dalam bahasa pemrograman aplikasi saat Anda menekan tombol atau mengklik elemen jendela, maka itu tidak mungkin. Baca kode sumber aplikasi, jika memungkinkan untuk mendapatkannya. Anda dapat menggunakan dconf watch /untuk melihat pengaturan apa yang sedang diubah, tetapi tidak bagaimana hal itu dilakukan.

Secara teknis, jika Anda tahu cara mengoperasikan debugger, membaca alamat memori, dan mengetahui beberapa bahasa rakitan, maka Anda dapat mengetahui apa yang dilakukan aplikasi pada tingkat CPU dan memori. Ini dikenal sebagai rekayasa balik perangkat lunak dan sering digunakan oleh para profesional keamanan untuk menganalisis perangkat lunak berbahaya dan menemukan kerentanan dalam perangkat lunak yang sah.

Apakah aplikasi ini membuka terminal di latar belakang dan menjalankan perintah ini?

Tidak, tidak ada terminal yang terpasang. Banyak program tahu di mana dconfbasis data untuk pengguna berada dan menulis di sana. Ada juga bus komunikasi antar-proses yang dikenal sebagai dbus, tempat program dapat mengirim sinyal, dan sebuah program akan seperti "Hei, itu pesan untuk saya!"

Tambahan

  • Bisakah aplikasi menjalankan aplikasi lain? Ya, itu dilakukan melalui panggilan standar fork()dan execve()sistem. Inti dari menciptakan proses di Linux dan sistem * nix lainnya sebagian besar didasarkan pada kedua hal ini. Mekanisme shell untuk menjalankan perintah non-builtin banyak menggunakan itu. Ketika Anda menjalankan secara interaktif

    $ ls 
    

    shell akan membuat proses baru via fork(), proses itu akan berjalan execve() yang akan dimulai ls. Karena bagaimana execve()proses bercabang baru itu akan terjadi ls. The pipe()system call adalah apa yang akan membantu membaca kembali output ls. Saya sangat menyarankan membaca jawaban saya untuk Apa perbedaan antara pipa dan pengalihan untuk memahami bagaimana mekanisme pipa bekerja - itu bukan hanya |operator, tetapi sebenarnya syscall.

  • Bisakah aplikasi menjalankan perintah shell? Tidak. Sintaks shell hanya dipahami oleh shell itu sendiri. Apa yang dapat Anda lakukan, bagaimanapun, adalah memulai shell dengan -csaklar baris perintah dan memberikan perintah yang sesuai. Ini sering digunakan untuk pintasan khusus yang diatur dalam GNOME atau lingkungan desktop lainnya, karena pintasan khusus beroperasi pada executable dan tidak ada shell untuk memahami sintaks. Jadi sebagai contoh, Anda akan lakukan bash -c 'xdotool key Ctrl+Alt+T'untuk menjalankan xdotoolperintah atau bash -c 'cd $HOME/Desktop; touch New_File'membuat file baru di desktop secara tidak langsung melalui pintasan. Ini adalah contoh yang sangat menarik karena Anda dapat menggunakan variabel shell, karena Anda menggunakan shell secara eksplisit.

Sergiy Kolodyazhnyy
sumber
2
Terima kasih banyak @Serg untuk penjelasan terperinci dan menjawab setiap pertanyaan secara terpisah dan sistematis!
ptmdevncoder
@Logan kesenangan saya, selalu senang untuk membantu :)
Sergiy Kolodyazhnyy
1
Untungnya, sumber untuk alat-alat tersebut tersedia karena FLOSS. Karena itu saya akan mengatakan membalikkan mereka sedikit berlebihan dalam hal ini. :)
Andrea Lazzarotto
1
@AndreaLazzarotto Yep, Unity Tweak Tool dan editor Dconf - itu adalah open source, jadi tidak perlu lagi merekayasa balik. Dalam jawaban saya, saya menjaga semuanya sangat umum dan mencoba untuk menutupi tidak hanya alat-alat itu, tetapi kemungkinan lain
Sergiy Kolodyazhnyy
Lebih cepat jarang menjadi titik untuk aplikasi GUI. Melarikan diri atau menyusun nilai-nilai untuk digunakan dengan alat shell itu membosankan, mudah salah dan tidak berguna jika Anda bisa menggunakan perpustakaan. Re debugging: Jika aplikasi diinstal dengan simbol debug dan ditulis dalam bahasa yang didukung oleh gdb (pada debian misalnya dengan menginstal paket -dbg yang sesuai), Anda tidak perlu tahu assembler: gdb akan menunjukkan kepada Anda kode sumber menggunakan info debug saat Anda menelusuri aplikasi. Apa yang akan lebih sulit adalah menemukan titik masuk yang tepat untuk memulai debugging, karena boilerplate GUI yang membosankan.
Jonas Schäfer
21

Memata-matai apa yang terjadi

Sebagian besar yang dilakukan editor pengaturan ini dapat ditonton dengan menjalankan

dconf watch /

di terminal.

gsettings

Juga sebagian besar waktu, untuk mencapai apa yang Anda lihat terjadi dengan perintah di atas, aplikasi ini perlu mengedit dconfdatabase (lebih lanjut di bawah). Ini dapat dilakukan secara langsung , dengan menggunakan opsi cli dari dconf (yang tidak disukai), atau dengan menjalankan gsettingsperintah yang sesuai , seperti yang Anda sebutkan.

Untuk menjalankan perintah ini, tidak ada jendela terminal yang diperlukan, seperti yang Anda lihat pada contoh.

Tentang, gsettings, dconf, dan basis data dconf

gsettingsadalah cli frontend to dconf, yang pada gilirannya mengedit dconfdatabase, di mana sebagian besar pengaturan disimpan, dalam format biner. Lihat juga jawaban yang bagus ini .

The dconfDatabase, by the way, juga dapat diedit dari GUI oleh dconfredaksi, yang dalam repositori:

masukkan deskripsi gambar di sini

Sampel kerja

Sebuah. Dengan python

masukkan deskripsi gambar di sini

Untuk menunjukkan kepada Anda apa yang terjadi di bawah tenda, di bawah sampel yang berfungsi untuk beralih posisi peluncur Anda dari GUI dalam satu tombol (beralih):

#!/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()
  • Tempel kode ke dalam kosong file.py
  • jalankan dengan perintah:

    python3 /path/to/file.py
    

...dan bersenang-senang.

b. Ikon peluncur

Bahkan peluncur sederhana dapat melakukan pekerjaan dari GUI:

masukkan deskripsi gambar di sini

[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
  • Rekatkan kode ke file kosong, simpan sebagai setlauncher.desktop
  • Seret ke peluncur dan klik kanan

Untuk penggunaan permanen, simpan di ~/.local/share/applications(untuk penggunaan lokal) atau ~/usr/share/applicationsuntuk semua pengguna.

Yakub Vlijm
sumber
@Logan tidak menyebutkannya :)
Jacob Vlijm