web-dev-qa-db-ja.com

モニターが接続されているときにスクリプトを実行する

外部モニターをラップトップに接続するときに、usr/local/bin/にあるスクリプトを実行しようとしています。新しいudevルールを追加しようとしましたが、うまくいきませんでした。 /etc/udev/rules.dという新しいファイルをvga-monitor-connect.rulesに作成しました。ファイルの内容は

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

この答え から行を取りました

オンラインで検索した後、次のルールも試しました

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

しかし、これも機能しませんでした。

私はスクリプトを手動で実行しましたが、スクリプトに問題がないように機能することを確認できます。

また、udevについてあまり知らないため、使用したルールが間違っている可能性があることを明確にしたいと思います。誰かが私の問題の適切なルールを知っているなら、答えを残してください。

グラフィックカードはIntel GM965統合チップセットです。

12
Rumesh

画面が接続または切断された場合にコマンドを実行する代替方法

別の解決策は、小さなバックグラウンドスクリプトを実行することです。以下のスクリプトをバックグラウンドで実行すると、プロセッサの負荷の増加をまったく測定できませんでした。

2番目の画面が接続または切断されるたびに、スクリプトまたはその他のコマンドを実行するための簡単で便利な方法です。

サンプルスクリプト

  • コマンドxrandrの出力に文字列 "connected"が何回現れるかを5秒ごとにチェックします( "connected"の後のスペースに注意して、 "disconnected"との誤った一致を防ぎます)。各オカレンスは、接続された画面を表します。
  • 発生回数が変化した場合、画面が接続されたか切断されました。変更はスクリプトによって「認識」され、コマンドに接続できます。スクリプトのheadセクションで設定できます。

スクリプト

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

使い方

  1. スクリプトを空のファイルにコピーし、connect_screen.pyとして保存します
  2. ヘッドセクションで、接続時に実行するコマンドを設定します(例として「gedit」を設定します。引用符に注意してください)。同様に、切断時にコマンドを設定することもできます。それ以外の場合は、disconnect_command = ""をそのままにします。

    If disconnect-コマンドを使用し、行のコメントも外します:

    run_command(disconnect_command)
    

    行をコメントアウトします:

    pass
    

    スクリプトに示されているとおり

  3. 端末からスクリプトをテスト実行し、画面を接続して、すべてが正常に機能するかどうかを確認します。
  4. すべてが正常に機能する場合は、スタートアップアプリケーションに追加します。[ダッシュ]> [スタートアップアプリケーション]> [コマンドを追加]:

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

    sleep 15は、スクリプトが実行を開始する前にデスクトップを完全に起動することです。念のため。


編集

「スマート」な方法で起動時にスクリプトを実行する方法。

sleep 15のブレークは一般的には機能するはずですが、起動時間はシステムごとに異なるため、適切なブレーク時間を見つけるには多少の実験が必要になる場合があります。少し追加するだけで、スクリプトは「スマート」になり、xrandrコマンドが成功するのを待ってから実際のスクリプトを開始します。以下のバージョンを使用する場合、コマンドを追加するだけです。

python3 /path/to/connect_screen.py

スタートアップアプリケーションに。以降の使用法は、上記のバージョンとまったく同じです。

スクリプト

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

これは、次のbashスクリプトからも実現できます。

#!/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
2
Bhaskar K C