Ứng dụng dựa trên GUI có thực thi các lệnh shell trong nền không?


29

Tôi đã chuyển sang Ubuntu 16.04 chỉ 2 ngày trước từ Windows. Tôi thích cách chúng ta có thể tùy chỉnh Unity Desktop. Tôi chỉ chơi xung quanh với giao diện của môi trường Desktop. Giống như trong Windows, tôi muốn trình khởi chạy ở dưới cùng của màn hình. Trên Googling, tôi tìm thấy một lệnh như sau:

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

Ngoài ra, còn có trình soạn thảo unity-Tune-tool và dconf để hoàn thành công việc. Nhưng đây là cách tiếp cận GUI để hoàn thành công việc.

Câu hỏi của tôi là:

  • Các ứng dụng dựa trên GUI này cũng thực hiện cùng một lệnh trong nền?
  • Làm thế nào để có một peep tại hoạt động nội bộ của các ứng dụng này? Ý tôi là, có cách nào thực sự nhìn vào các lệnh đang được thực thi tại mỗi lần nhấp vào nút không?
  • Các ứng dụng này có mở ra một thiết bị đầu cuối trong nền và thực hiện các lệnh này không?

Câu trả lời ở đây cho biết làm thế nào để có được bộ mô tả tệp tiêu chuẩn của quy trình. Nhưng, tôi đã không nhận được bất cứ điều gì trong đầu ra.

Hơn nữa, strace -p pid -o output.txtlệnh ném một lượng lớn văn bản vào tệp.

Vì vậy, trong ngắn hạn, làm việc bằng cách sử dụng các ứng dụng GUI giống như làm công cụ từ dòng lệnh?

Câu trả lời:


35

Các ứng dụng dựa trên GUI này cũng thực hiện cùng một lệnh trong nền?

Có và không. Họ viết vào dconfcơ sở dữ liệu của các cài đặt, nhưng họ có thể sử dụng các cách khác nhau để làm như vậy. Các chương trình được viết bằng Python có thể sẽ sử dụng gi.repository.Giomô-đun (tôi biết vì tôi sử dụng nó rất nhiều) hoặc thay vào đó chúng có thể sử dụng gsettingsnhư một lệnh bên ngoài bằng cách gọi subprocess.Popen(['gsettings','org.some.schema','some-key','value'])và về cơ bản nó sẽ chạy như một lệnh shell. Chương trình AC sẽ sử dụng một cái gì đó tương tự, có thể là một gio.hthư viện hoặc thậm chí nó có thể sử dụng exec()họ các hàm để làm tương tự như Popentrong python. Vì vậy, để trả lời câu hỏi tiêu đề của bạn: "Ứng dụng dựa trên GUI có thực thi các lệnh shell trong nền không?" Họ có thể, nhưng có thể không cần thiết vì có thư viện cho bất kỳ ngôn ngữ nào mà ứng dụng được viết và có thể sẽ nhanh hơn một chút để sử dụng chức năng thư viện, hơn là tạo ra một quy trình mới.

Để cung cấp cho bạn một mẫu về cách nó được thực hiện với các thư viện / mô-đun, vui lòng xem mã nguồn của chỉ báo danh sách trình khởi chạy của tôi . Ở đó tôi đã viết một hàm để tạo một thể hiện của Gio.Settingslớp và sau đó sử dụng nó để sửa đổi trình khởi chạy Unity tùy thuộc vào loại danh sách bạn muốn có ở đó.

Làm thế nào để có một peep tại hoạt động nội bộ của các ứng dụng này? Ý tôi là, có cách nào thực sự nhìn vào các lệnh đang được thực thi tại mỗi lần nhấp vào nút không?

Không. Nếu bạn muốn xem lệnh nào được ban hành trong ngôn ngữ lập trình của ứng dụng đó khi bạn nhấn nút hoặc nhấp vào các yếu tố cửa sổ, thì không thể. Đọc mã nguồn của ứng dụng, nếu có thể lấy được nó. Bạn có thể sử dụng dconf watch /để xem cài đặt nào đang được thay đổi, nhưng không phải cách thực hiện.

Về mặt kỹ thuật, nếu bạn biết cách vận hành trình gỡ lỗi, đọc địa chỉ bộ nhớ và biết một số ngôn ngữ lắp ráp, thì bạn có thể biết ứng dụng làm gì ở cấp độ CPU và bộ nhớ. Đây được gọi là kỹ thuật đảo ngược phần mềm và thường được các chuyên gia bảo mật sử dụng để phân tích phần mềm độc hại và phát hiện ra các lỗ hổng trong phần mềm hợp pháp.

Các ứng dụng này có mở ra một thiết bị đầu cuối trong nền và thực hiện các lệnh này không?

Không, không có thiết bị đầu cuối kèm theo. Nhiều chương trình biết dconfcơ sở dữ liệu cho người dùng được đặt ở đâu và viết ở đó. Ngoài ra còn có một xe buýt liên lạc giữa các quá trình được gọi là dbus, nơi các chương trình có thể gửi tín hiệu và một chương trình sẽ giống như "Này, đó là một thông điệp cho tôi!"

Phụ lục

  • Các ứng dụng có thể chạy các ứng dụng khác không? Vâng, điều đó được thực hiện thông qua các cuộc gọi hệ thống fork()và tiêu chuẩn execve(). Bản chất của việc tạo các quy trình trên Linux và các hệ thống * nix khác chủ yếu dựa trên hai hệ thống này. Cơ chế Shell để chạy các lệnh không dựng sẵn đặc biệt sử dụng rất nhiều. Khi bạn chạy tương tác

    $ ls 
    

    Shell sẽ tạo ra một quy trình mới thông qua fork(), quá trình đó sẽ chạy execve() sẽ bắt đầu ls. Bởi vì execve()quá trình rẽ nhánh mới sẽ như thế nào ls. Cuộc pipe()gọi hệ thống là những gì sẽ giúp đọc lại đầu ra của ls. Tôi thực sự khuyên bạn nên đọc câu trả lời của mình cho sự khác biệt giữa đường ống và chuyển hướng để hiểu cách thức hoạt động của cơ chế đường ống - nó không chỉ là |nhà điều hành, mà thực sự là một tòa nhà.

  • Các ứng dụng có thể chạy các lệnh shell? Không. Cú pháp Shell chỉ được hiểu bởi chính shell. Tuy nhiên, những gì bạn có thể làm là bắt đầu một trình bao với một -ccông tắc dòng lệnh và cung cấp các lệnh thích hợp. Điều này thường được sử dụng cho các phím tắt tùy chỉnh được đặt trong Gnome hoặc các môi trường máy tính để bàn khác, vì các phím tắt tùy chỉnh hoạt động trên các tệp thực thi và không có vỏ để hiểu cú pháp. Vì vậy, như một ví dụ, bạn sẽ làm bash -c 'xdotool key Ctrl+Alt+T'để gián tiếp chạy xdotoollệnh hoặc bash -c 'cd $HOME/Desktop; touch New_File'tạo tệp mới trên máy tính để bàn thông qua phím tắt. Đây là ví dụ đặc biệt thú vị khi bạn có thể sử dụng biến shell, vì bạn đang sử dụng shell rõ ràng.


2
Cảm ơn bạn rất nhiều @Serg đã giải thích chi tiết và trả lời từng câu hỏi một cách riêng biệt và có hệ thống!
ptmdevncoder

@Logan niềm vui của tôi, luôn sẵn lòng giúp đỡ :)
Sergiy Kolodyazhnyy

1
May mắn thay, nguồn cho các công cụ được đề cập là có sẵn vì chúng là FLOSS. Vì vậy, tôi sẽ nói đảo ngược chúng là một chút quá mức trong trường hợp này. :)
Andrea Lazzarotto

1
@AndreaLazzarotto Yep, Unity Tweak Tool và trình soạn thảo Dconf - đó là những nguồn mở, vì vậy không cần thiết phải đảo ngược những thứ đó. Trong câu trả lời của mình, tôi giữ mọi thứ rất chung chung và cố gắng bao quát không chỉ những công cụ đó, mà cả những khả năng khác
Sergiy Kolodyazhnyy

Nhanh hơn hiếm khi là điểm cho các ứng dụng GUI. Thoát hoặc sắp xếp các giá trị để sử dụng với công cụ shell là tẻ nhạt, dễ bị sai và vô nghĩa nếu bạn chỉ có thể sử dụng thư viện. Gỡ lỗi lại: Nếu ứng dụng được cài đặt các ký hiệu gỡ lỗi và được viết bằng ngôn ngữ được hỗ trợ bởi gdb (trên debian, ví dụ: bằng cách cài đặt gói -dbg tương ứng), bạn không cần phải biết trình biên dịch mã: gdb sẽ hiển thị cho bạn mã nguồn bằng cách sử dụng gỡ lỗi thông tin trong khi bạn bước qua ứng dụng. Điều khó khăn hơn là tìm một điểm vào thích hợp để bắt đầu gỡ lỗi, vì bản tóm tắt GUI nhàm chán.
Jonas Schäfer

21

Theo dõi những gì xảy ra

Hầu hết những gì các trình soạn thảo cài đặt này có thể được xem bằng cách chạy

dconf watch /

trong một thiết bị đầu cuối.

gsinstall

Ngoài ra, hầu hết thời gian, để đạt được những gì bạn thấy xảy ra với lệnh trên, các ứng dụng này sẽ cần phải chỉnh sửa dconfcơ sở dữ liệu (hơn nữa bên dưới). Điều này có thể được thực hiện trực tiếp , bằng cách sử dụng các tùy chọn cli của dconf (không được ưa thích) hoặc bằng cách chạy các gsettingslệnh tương ứng , như cách bạn đề cập.

Để chạy các lệnh này, không cần cửa sổ đầu cuối, như bạn có thể thấy trong các ví dụ.

Giới thiệu, gsinstall, dconf và cơ sở dữ liệu dconf

gsettingslà lối vào cli dconf, đến lượt nó chỉnh sửa dconfcơ sở dữ liệu, nơi hầu hết các cài đặt được lưu trữ, ở định dạng nhị phân. Xem thêm câu trả lời tốt đẹp này .

Nhân tiện dconf, cơ sở dữ liệu cũng có thể được chỉnh sửa từ GUI bằng dconftrình chỉnh sửa , nằm trong kho:

nhập mô tả hình ảnh ở đây

Mẫu làm việc

a. Trong trăn

nhập mô tả hình ảnh ở đây

Để cho bạn thấy những gì xảy ra dưới mui xe, bên dưới một mẫu đang hoạt động để chuyển vị trí trình khởi chạy của bạn từ GUI trong một nút (chuyển đổi) duy nhất:

#!/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()
  • Dán mã vào chỗ trống file.py
  • chạy nó bằng lệnh:

    python3 /path/to/file.py
    

... và vui chơi.

b. Biểu tượng trình khởi chạy

Ngay cả một trình khởi chạy đơn giản cũng có thể thực hiện công việc từ GUI:

nhập mô tả hình ảnh ở đây

[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
  • Dán mã vào một tệp trống, lưu nó dưới dạng setlauncher.desktop
  • Kéo nó vào trình khởi chạy và nhấp chuột phải

Để sử dụng vĩnh viễn, lưu trữ nó trong ~/.local/share/applications(để sử dụng cục bộ) hoặc ~/usr/share/applicationscho tất cả người dùng.


@Logan đừng đề cập đến nó :)
Jacob Vlijm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.