GUI tabanlı uygulama arka planda kabuk komutları yürütür mü?


29

Sadece 2 gün önce Windows’tan Ubuntu 16.04’e geçtim. Birlik Masaüstü'nü özelleştirebilmemizden hoşlanıyorum. Ben sadece masaüstü ortamının görünüşü ve hissi ile oynuyorum. Tıpkı Windows'ta olduğu gibi, başlatıcının ekranın altında olmasını istedim. Googling'de şöyle bir komut buldum:

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

Ayrıca, işi yapmak için unity-tweak-tool ve dconf editörü vardır. Ancak bunlar GUI'nin yapılması gerekenler.

Benim sorularım:

  • Bu GUI tabanlı uygulamalar da aynı komutu arka planda mı yürütüyor?
  • Bu uygulamaların iç işleyişinde nasıl dikizlemek? Yani, her düğmeye basıldığında yürütülen komutlara bakmanın bir yolu var mı?
  • Bu uygulamalar arka planda bir terminal açıp bu komutları yerine getiriyor mu?

Cevap burada sürecin standart dosya tanımlayıcısı nasıl söyler. Ancak çıktıda hiçbir şey bulamadım.

Ayrıca, strace -p pid -o output.txtkomut dosyaya çok miktarda metin atıyor.

Yani, kısaca, GUI uygulamalarını kullanarak bir şeyler yapmak, komut satırından bir şeyler yapmakla aynı mıdır?

Yanıtlar:


35

Bu GUI tabanlı uygulamalar da aynı komutu arka planda mı yürütüyor?

Evet ve hayır. dconfAyarlar veritabanına yazıyorlar , ancak bunu yapmak için farklı yollar kullanıyor olabilirler. Python'da yazılmış programlar muhtemelen gi.repository.Giomodülü kullanacak (bunu çok fazla kullanıyorum çünkü biliyorum) veya bunun yerine gsettingsharici bir komut olarak kullanabilirler subprocess.Popen(['gsettings','org.some.schema','some-key','value'])ve temel olarak bir kabuk komutu olarak çalışacaktır. AC programı benzer bir şey, muhtemelen bir gio.hkütüphane kullanır veya hatta python'daki exec()gibi yapmak için fonksiyon ailesini kullanabilir Popen. Bu yüzden başlık sorunuzu cevaplamak için: "GUI tabanlı uygulama arka planda kabuk komutları yürütüyor mu?" Yapabilirler, ancak muhtemelen gerekli değildir, çünkü uygulamanın hangi dilde yazıldığına bakılmaksızın bir kütüphane vardır ve bir kütüphane işlevini kullanmak, yeni bir süreç oluşturmaktan daha hızlı olacaktır.

Kütüphaneler / modüller ile nasıl yapıldığına dair bir örnek vermek için, başlatıcı listem göstergesinin kaynak koduna göz atmaktan çekinmeyin . Orada Gio.Settingssınıfın bir örneğini oluşturmak için bir fonksiyon yazdım ve sonra orada olmasını istediğiniz listenin türüne bağlı olarak Unity başlatıcısını değiştirmek için kullanın.

Bu uygulamaların iç işleyişinde nasıl dikizlemek? Yani, her düğmeye basıldığında yürütülen komutlara bakmanın bir yolu var mı?

Hayır. Bir düğmeye basarken veya pencere öğelerini tıkladığınızda bu uygulamanın programlama dilinde hangi komutun verildiğini görmek istiyorsanız, bu mümkün değildir. Uygulamanın kaynak kodunu okumak mümkün ise okuyun. dconf watch /Hangi ayarların değiştirildiğini görmek için kullanabilirsiniz , ancak nasıl yapıldığını değil.

Teknik olarak, bir hata ayıklayıcısını nasıl çalıştıracağınızı, bellek adreslerini nasıl okuyacağınızı ve bazı montaj dilini biliyorsanız, bir uygulamanın CPU ve bellek düzeyinde ne yaptığını öğrenebilirsiniz. Bu, yazılım tersine mühendislik olarak bilinir ve güvenlik uzmanları tarafından kötü amaçlı yazılımları analiz etmek ve yasal yazılımlardaki güvenlik açıklarını keşfetmek için sıkça kullanılır.

Bu uygulamalar arka planda bir terminal açıp bu komutları yerine getiriyor mu?

Hayır, ekli terminal yok. Birçok program dconfkullanıcının veritabanının nerede olduğunu bilir ve orada yazar. dbusProgramların sinyal gönderebileceği ve “Hey, bu benim için bir mesaj!” Gibi bir süreçler arası iletişim veri yolu da var.

ek

  • Uygulamalar başka uygulamaları çalıştırabilir mi? Evet, standart fork()ve execve()sistem çağrıları aracılığıyla yapılır . Linux ve diğer * nix sistemlerinde süreç yaratmanın özü büyük ölçüde bu ikisine dayanmaktadır. Yerleşik olmayan komutları çalıştırmak için kullanılan kabuk mekanizması özellikle bunu çok kullanır. Etkileşimli olarak çalıştırdığınızda

    $ ls 
    

    Kabuk yeni bir işlem yaratacak , başlayacak olan fork()işlem devam execve()edecek ls. Bu execve()yeni çatal işlemin nasıl olacağından dolayı ls. pipe()Sistem çağrısı çıktısını geri okumak yardımcı olacaktır şeydir ls. Boru mekanizmasının nasıl çalıştığını anlamak için boru ile yönlendirme arasındaki fark nedir? Cevabını okumanızı şiddetle tavsiye ediyorum - bu sadece |operatör değil , aynı zamanda bir sistem çağrısı.

  • Uygulamalar kabuk komutlarını çalıştırabilir mi? Hayır. Shell sözdizimi yalnızca kabuğun kendisi tarafından anlaşılır. Ancak, yapabileceğiniz şey bir komut satırı -canahtarıyla bir kabuk başlatmak ve uygun komutları sağlamaktır. Bu genellikle GNOME'da veya diğer masaüstü ortamlarında ayarlanan özel kısayollar için kullanılır, çünkü özel kısayollar çalıştırılabilir dosyalarda çalışır ve sözdizimini anlamak için bir kabuk yoktur. Bu nedenle, bir örnek olarak, bash -c 'xdotool key Ctrl+Alt+T'dolaylı olarak xdotoolkomutu çalıştırmak veya bash -c 'cd $HOME/Desktop; touch New_File'masaüstünde kısayol aracılığıyla yeni dosya oluşturmak için yapardınız . Bu, özellikle bir kabuk kullandığınız için bir kabuk değişkeni kullanabileceğiniz için ilginç bir örnektir.


2
Ayrıntılı açıklama ve her bir soruyu ayrı ayrı ve sistematik olarak yanıtladığınız için teşekkür ederiz.
ptmdevncoder

:) yardım için memnun hep benim zevk, @Logan
Sergiy Kolodyazhnyy

1
Neyse ki, söz konusu araçların kaynağı FLOSS olduğundan kaynaklanmaktadır. Bu nedenle, onları tersine çevirmenin bu durumda biraz fazlaca olduğunu söyleyebilirim. :)
Andrea Lazzarotto 15:16

1
@AndreaLazzarotto Yep, Unity Tweak Tool ve Dconf editörü - bunlar açık kaynak kodludur, bu yüzden bunları tersine çevirmeye gerek yoktur. Cevabımda her şeyi çok genel tuttum ve sadece bu araçları değil diğer olasılıkları da kapsamaya çalıştım
Sergiy Kolodyazhnyy

Daha hızlı GUI uygulamaları için nadiren nokta. Bir kabuk aracıyla kullanmak için değerlerden kaçma veya marşaling, yalnızca kütüphaneyi kullanabiliyorsanız sıkıcı, yanlış ve kolay anlaşılabilirdir. Yeniden hata ayıklama: Eğer uygulama hata ayıklama sembolleriyle kuruluysa ve gdb tarafından desteklenen bir dilde yazılmışsa (örneğin debian'da - karşılık gelen bir -dbg paketi yükleyerek), assembler'ı bilmeniz gerekmez: gdb kaynak kodunu kullanarak kodunu gösterir. Uygulama boyunca adım adım hata ayıklama bilgisi. Daha zor olacak, sıkıcı GUI kazan plakası nedeniyle hata ayıklamaya başlamak için uygun bir giriş noktası bulmak.
Jonas Schäfer,

21

Olanları gözetlemek

Bu ayar editörlerinin yaptıklarının çoğu, çalıştırılarak izlenebilir.

dconf watch /

bir terminalde.

gsettings

Ayrıca, çoğu zaman, yukarıdaki komutla neler olduğunu gördüklerinizi elde etmek için, bu uygulamaların dconfveritabanını düzenlemesi gerekecektir (aşağıda). Bu, doğrudan , dconf'un cli seçeneklerini kullanarak (tercih edilmeyen) ya da gsettingsbahsettiğiniz gibi karşılık gelen komutları çalıştırarak yapılabilir .

Bu komutları çalıştırmak için, örneklerde de görebileceğiniz gibi terminal penceresine gerek yoktur.

Hakkında, gsettings, dconf ve dconf veritabanı

gsettingsdconfsırayla dconfayarların çoğunun saklandığı veritabanını ikili biçimde düzenleyen cli frontend'tir . Ayrıca bu güzel cevaba bakınız .

Bu dconfarada, veritabanı GUI'den dconfeditör tarafından , depolardaki düzenleyici tarafından da düzenlenebilir :

görüntü tanımını buraya girin

Çalışma örnekleri

a. Python'da

görüntü tanımını buraya girin

Kaputun altında neler olduğunu göstermek için, bir çalışma örneğinin altında, başlatıcı konumunuzu GUI'den tek bir (geçiş) düğmesiyle değiştirmek için:

#!/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()
  • Kodu boşa yapıştırın file.py
  • komutuyla çalıştırın:

    python3 /path/to/file.py
    

...ve eğlen.

b. Başlatıcı simgesi

Basit bir başlatıcı bile GUI'den işi yapabilir:

görüntü tanımını buraya girin

[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
  • Kodu boş bir dosyaya yapıştırın, olarak kaydedin. setlauncher.desktop
  • Başlatıcıya sürükleyin ve sağ tıklayın

Kalıcı kullanım için, ~/.local/share/applications(yerel kullanım için) veya ~/usr/share/applicationstüm kullanıcılar için saklayın .


@Logan bundan bahsetmiyor :)
Jacob Vlijm
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.