Chạy script khi màn hình được kết nối


12

Tôi đang cố chạy tập lệnh nằm trong usr/local/bin/khi tôi kết nối màn hình ngoài với máy tính xách tay của mình. Tôi đã cố gắng thêm một udevquy tắc mới nhưng điều đó không hiệu quả. Tôi đã tạo một tập tin mới trong cuộc /etc/udev/rules.dgọi vga-monitor-connect.rules. Nội dung của tập tin là

SUBSYSTEM=="drm", ACTION=="change", RUN+="/usr/local/bin/panel-fix"

Tôi lấy dòng từ câu trả lời này

Sau khi tìm kiếm trực tuyến tôi cũng đã thử quy tắc sau

KERNEL=="card0", SUBSYSTEM=="drm", ENV{DISPLAY}=":0", ENV{XAUTHORITY}="/home/rumesh/.Xauthority", RUN+="/usr/local/bin/panel-fix"

Tuy nhiên điều này cũng không hoạt động.

Tôi đã chạy tập lệnh theo cách thủ công và tôi có thể xác nhận rằng nó hoạt động để nó không thành vấn đề với tập lệnh của tôi.

Tôi cũng muốn làm rõ rằng tôi không biết nhiều về udevquy tắc mà tôi đã sử dụng có thể sai. Nếu bất cứ ai biết quy tắc thích hợp cho vấn đề của tôi xin vui lòng để lại câu trả lời.

Card đồ họa của tôi là chipset tích hợp Intel GM965


Bạn có đặc biệt muốn làm điều đó như thế này? Một kịch bản nền nhỏ sẽ là một miếng bánh.
Jacob Vlijm

@JacobVlijm Kịch bản sẽ như thế nào? Bạn có thể đưa ra một ví dụ.
Rumesh

Có phải chỉ để kích hoạt nếu (bất kỳ) màn hình thứ hai được gắn?
Jacob Vlijm

Có, tôi cần chạy tập lệnh của riêng mình khi đính kèm màn hình thứ hai
Rumesh

1
Không có vấn đề gì, hãy dành thời gian và trả lời khi bạn có thể :)
Rumesh

Câu trả lời:


7

Một cách khác để chạy lệnh nếu màn hình được kết nối hoặc ngắt kết nối

Một giải pháp thay thế sẽ là chạy một kịch bản nền nhỏ. Chạy đoạn script bên dưới trong nền, tôi không thể đo bất kỳ sự gia tăng nào của tải bộ xử lý.

Đây là một cách dễ dàng để chạy tập lệnh hoặc bất kỳ lệnh nào khác, bất cứ khi nào màn hình thứ hai được kết nối hoặc ngắt kết nối.

Kịch bản ví dụ

  • Chỉ cần kiểm tra cứ sau 5 giây số lần chuỗi "được kết nối" xuất hiện trong đầu ra của lệnh xrandr(lưu ý khoảng trắng sau khi "được kết nối" để ngăn kết quả khớp sai với "ngắt kết nối"). Mỗi lần xuất hiện đại diện cho một màn hình được kết nối.
  • Nếu số lần xuất hiện thay đổi, một màn hình đã được kết nối hoặc ngắt kết nối. Thay đổi được "chú ý" bởi tập lệnh và có thể được kết nối với một lệnh, bạn có thể đặt trong phần đầu của tập lệnh.

Kịch bản

#!/usr/bin/env python3
import subprocess
import time

#--- set both commands (connect / disconnect) below
connect_command = "gedit"
disconnect_command = ""
#---

def get(cmd): return subprocess.check_output(cmd).decode("utf-8")
# - to count the occurrenc of " connected "
def count_screens(xr): return xr.count(" connected ")
# - to run the connect / disconnect command(s)
def run_command(cmd): subprocess.Popen(["/bin/bash", "-c", cmd])

# first count
xr1 = None

while True:
    time.sleep(5)
    # second count
    xr2 = count_screens(get(["xrandr"]))
    # check if there is a change in the screen state
    if xr2 != xr1:
        print("change")
        if xr2 == 2:

            # command to run if connected (two screens)
            run_command(connect_command)
        elif xr2 == 1:
            # command to run if disconnected (one screen)
            # uncomment run_command(disconnect_command) to enable, then also comment out pass
            pass
            # run_command(disconnect_command)
    # set the second count as initial state for the next loop
    xr1 = xr2

Cách sử dụng

  1. Sao chép tập lệnh vào một tập tin trống, lưu nó dưới dạng connect_screen.py
  2. Trong phần đầu, đặt lệnh để chạy trên kết nối (Tôi đặt "gedit" làm ví dụ, chú ý các trích dẫn). Ngoài ra, có thể thiết lập một lệnh trên ngắt kết nối, tương tự. Khác đi disconnect_command = ""như nó là.

    Nếu bạn sử dụng lệnh ngắt kết nối, đồng thời bỏ dòng:

    run_command(disconnect_command)

    và nhận xét ra dòng:

    pass

    Như được chỉ ra trong kịch bản

  3. Chạy thử tập lệnh từ thiết bị đầu cuối, kết nối màn hình của bạn và xem tất cả có hoạt động tốt không.
  4. Nếu tất cả đều hoạt động tốt, hãy thêm nó vào các ứng dụng khởi động của bạn: Dash> Ứng dụng khởi động> Thêm lệnh:

    /bin/bash -c "sleep 15&&python3 /path/to/connect_screen.py"

    Các sleep 15là làm cho máy tính để bàn khởi động hoàn toàn trước khi kịch bản bắt đầu chạy. Chỉ để chắc chắn.


BIÊN TẬP

Cách chạy tập lệnh khi khởi động theo cách "thông minh".

Việc nghỉ sleep 15nên hoạt động chung, nhưng vì thời gian khởi động khác nhau trên mỗi hệ thống, nên có thể cần một số thử nghiệm để tìm thời gian nghỉ phù hợp. Với một bổ sung nhỏ, tập lệnh trở nên "thông minh" và chờ xrandrlệnh thành công trước khi bắt đầu tập lệnh thực tế. Nếu bạn sử dụng phiên bản dưới đây, bạn chỉ cần thêm lệnh:

python3 /path/to/connect_screen.py

cho các ứng dụng khởi động của bạn. Sử dụng thêm là chính xác như phiên bản trên.

Kịch bản

#!/usr/bin/env python3
import subprocess
import time

#--- set both commands (connect / disconnect) below
connect_command = "gedit"
disconnect_command = ""
#---

while True:
    time.sleep(5)
    try:
        subprocess.Popen(["xrandr"])
    except:
        pass
    else:
        break


# function to get the output of xrandr
def get(cmd): return subprocess.check_output(cmd).decode("utf-8")
# - to count the occurrenc of " connected "
def count_screens(xr): return xr.count(" connected ")
# - to run the connect / disconnect command(s)
def run_command(cmd): subprocess.Popen(["/bin/bash", "-c", cmd])

# first count
xr1 = None

while True:
    time.sleep(5)
    # second count
    xr2 = count_screens(get(["xrandr"]))
    # check if there is a change in the screen state
    if xr2 != xr1:
        if xr2 == 2:
            # command to run if connected (two screens)
            run_command(connect_command)
        elif xr2 == 1:
            # command to run if disconnected (one screen)
            # uncomment run_command(disconnect_command) to enable, then also comment out pass
            pass
            # run_command(disconnect_command)
    # set the second count as initial state for the next loop
    xr1 = xr2

4
Bạn đang tặng một chiếc xe đạp cho một người đàn ông bị hỏng xe nhanh thay vì sửa xe ...
solsTiCe

1
@solsTiCe 1. Đây không phải là xe đạp, mà là một lựa chọn chức năng hoàn hảo. Hãy nhớ rằng tất cả các thông báo-, sự kiện - hoặc bất kỳ hành động được thúc đẩy nào tồn tại bằng cách chạy một loại vòng lặp nào đó. 2. Tôi đề nghị bạn sửa chiếc Ferrari sau đó.
Jacob Vlijm

1
@Rumesh chạy các tập lệnh $PATH với phần mở rộng tập tin và với ngôn ngữ đi trước là một giải pháp không thanh lịch. Câu hỏi là nếu bạn muốn chạy nó cho một người dùng hoặc cho tất cả người dùng. Trong trường hợp cuối cùng, một thiết lập khác ngoài đề xuất là cần thiết, nhưng tốt nhất không phải là thiết lập bạn đang đề xuất :). Điều này sleep 15có thể không đủ, nhưng một giải pháp tao nhã hơn có thể là làm cho sự phá vỡ trở nên "thông minh", hãy để kịch bản thử / ngoại trừ khởi động cho đến khi quy trình khởi động "sẵn sàng" để kịch bản chạy. WOuld là một bổ sung nhỏ. Cho tôi biết.
Jacob Vlijm

1
Các tập lệnh @Rumesh $PATHkhông nên có phần mở rộng ngôn ngữ và có thể thực thi được, vì vậy hãy chạy mà không cần python3xem lintian.debian.org/tags/script-with-lingu-extension.html
Jacob Vlijm

1
@JacobVlijm Tôi đã thiết lập nó để có thể thực thi được trước đó vì vậy tôi đoán tôi chỉ có thể sử dụngconnect_screen
Rumesh

2

Điều này có thể đạt được từ sau bash script.

#!/usr/bin/env bash

xrandr=$(xrandr)

con_monitors=$(echo $xrandr | grep -c " connected ")

    if [[ $con_monitors -gt 1 ]]; then
        # All the layouts are saved in "screenlayout" folder.
        # eg cmd. xrandr --output HDMI-1 --mode 2560x1440 --pos 0x0 --rotate normal --output DP-1 --off --output eDP-1 --primary --mode 1920x1080 --pos 283x1440 --rotate normal --output DP-2 --off
        for layout in ~/.screenlayout/*.sh; do
            ./layout
        done
    fi
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.