Jalankan skrip saat monitor terhubung

12

Saya mencoba menjalankan skrip yang terletak usr/local/bin/ketika saya menghubungkan monitor eksternal ke laptop saya. Saya telah mencoba menambahkan udevaturan baru tetapi itu tidak berhasil. Saya membuat file baru dengan /etc/udev/rules.dnama vga-monitor-connect.rules. Isi file itu

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

Saya mengambil garis dari jawaban ini

Setelah mencari online saya juga mencoba aturan berikut

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

Namun ini juga tidak berhasil.

Saya telah menjalankan skrip secara manual dan saya dapat mengonfirmasi bahwa skrip tersebut berfungsi sehingga tidak ada masalah dengan skrip saya.

Saya juga ingin menjelaskan bahwa saya tidak tahu banyak tentang udevsehingga aturan yang saya gunakan mungkin salah. Jika ada yang tahu aturan yang tepat untuk masalah saya, silakan tinggalkan jawaban.

Kartu grafis saya adalah chipset terintegrasi Intel GM965

Rumesh
sumber
Apakah Anda secara khusus ingin melakukannya seperti ini? Script latar belakang kecil akan menjadi sepotong kue.
Jacob Vlijm
@JacobVlijm Bagaimana naskahnya? Bisakah Anda menunjukkan sebuah contoh.
Rumesh
Apakah hanya untuk memicu jika (ada) monitor kedua terpasang?
Jacob Vlijm
Ya saya perlu menjalankan skrip saya sendiri ketika saya lampirkan monitor kedua
Rumesh
1
Tidak masalah, luangkan waktu dan jawab ketika Anda bisa :)
Rumesh

Jawaban:

7

Cara alternatif untuk menjalankan perintah jika layar terhubung atau terputus

Solusi alternatif adalah menjalankan skrip latar belakang kecil. Menjalankan skrip di bawah ini di latar belakang, saya tidak bisa mengukur peningkatan beban prosesor apa pun.

Ini adalah cara mudah yang mudah untuk menjalankan skrip, atau perintah lainnya, setiap kali layar kedua terhubung atau terputus.

Contoh skrip

  • Cukup periksa setiap lima detik berapa kali string "terhubung" muncul dalam output perintah xrandr(ingat ruang setelah "terhubung" untuk mencegah kecocokan salah dengan "terputus"). Setiap kejadian mewakili layar yang terhubung.
  • Jika jumlah kemunculan berubah, layar dapat dihubungkan atau diputus. Perubahan "diperhatikan" oleh skrip dan dapat dihubungkan ke perintah, Anda dapat mengatur di bagian kepala skrip.

Naskah

#!/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

Cara Penggunaan

  1. Salin skrip ke file kosong, simpan sebagai connect_screen.py
  2. Di bagian kepala, setel perintah untuk dijalankan pada koneksi (saya set "gedit" sebagai contoh, ingat tanda kutip). Juga dimungkinkan untuk mengatur perintah pada disconnect. Lain pergi disconnect_command = ""seperti itu.

    Jika Anda menggunakan perintah disconnect-, batalkan komentar pada baris:

    run_command(disconnect_command)

    dan berikan komentar:

    pass

    Seperti yang ditunjukkan dalam skrip

  3. Uji-coba skrip dari terminal, sambungkan layar Anda dan lihat apakah semuanya berfungsi dengan baik.
  4. Jika semua berfungsi dengan baik, tambahkan ke aplikasi startup Anda: Dash> Aplikasi Startup> Tambahkan perintah:

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

    Ini sleep 15adalah untuk membuat desktop memulai sepenuhnya sebelum skrip mulai berjalan. Hanya untuk memastikan.


EDIT

Cara menjalankan skrip saat memulai dengan cara "pintar".

Waktu istirahat sleep 15seharusnya bekerja secara umum, tetapi karena waktu start up berbeda per sistem, Mungkin perlu beberapa percobaan untuk menemukan waktu istirahat yang tepat. Dengan tambahan kecil, skrip menjadi "pintar", dan menunggu xrandrperintah untuk berhasil sebelum memulai skrip yang sebenarnya. Jika Anda menggunakan versi di bawah ini, Anda hanya perlu menambahkan perintah:

python3 /path/to/connect_screen.py

ke Aplikasi Startup Anda. Penggunaan lebih lanjut persis sama dengan versi di atas.

Naskah

#!/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
Yakub Vlijm
sumber
4
Anda memberikan sepeda kepada seorang pria dengan mobil cepat yang rusak alih-alih memperbaiki mobil ...
solsTiCe
1
@solsTiCe 1. Ini bukan sepeda, tetapi merupakan opsi yang berfungsi sempurna. Perlu diingat bahwa semua tindakan pemberitahuan, peristiwa, atau apa pun yang didorong ada menjalankan semacam loop. 2. Saya sarankan Anda memperbaiki Ferrari.
Jacob Vlijm
1
@Rumesh menjalankan skrip $PATH dengan ekstensi file, dan dengan bahasa sebelumnya adalah solusi yang tidak terlalu elegan. Pertanyaannya adalah apakah Anda ingin menjalankannya untuk satu pengguna atau untuk semua pengguna. Dalam kasus terakhir, setup lain dari yang disarankan diperlukan, tetapi lebih disukai bukan yang Anda sarankan :). The sleep 15mungkin tidak cukup, tetapi solusi yang lebih elegan bisa membuat istirahat "pintar", biarkan script mencoba / kecuali untuk memulai sampai prosedur startup "siap" untuk script untuk menjalankan. Akan menjadi tambahan kecil. Biarkan aku tahu.
Jacob Vlijm
1
Skrip @Rumesh di $PATHseharusnya tidak memiliki ekstensi bahasa dan dapat dieksekusi, jadi jalankan tanpa python3melihat lintian.debian.org/tags/script-with-language-extension.html
Jacob Vlijm
1
@JacobVlijm Saya sudah mengaturnya untuk dieksekusi sebelum jadi saya kira saya bisa menggunakanconnect_screen
Rumesh
2

Ini dapat dicapai dari mengikuti skrip bash juga.

#!/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
Bhaskar KC
sumber