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


12

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統合チップセットです。


具体的にこのようにしたいですか?小さな背景スクリプトは簡単です。
ジェイコブVlijm

@JacobVlijmスクリプトはどうですか?例を示してください。
ルメシュ

(任意の)2番目のモニターが接続されている場合にのみトリガーしますか?
ジェイコブVlijm

はい、2番目のモニターを接続するときに独自のスクリプトを実行する必要があります
-Rumesh

1
問題ありません。時間をかけて、できる限り答えてください:)
ルメシュ

回答:


7

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

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

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

サンプルスクリプト

  • コマンドの出力に文字列 "connected"が何回現れるかを5秒ごとに単純にチェックしますxrandr( "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 = ""場合はそのままにします。

    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

4
あなたは、車を修理する代わりに、壊れた高速車を持つ男性に自転車を与えています
...-solsTiCe

1
@solsTiCe 1.これは自転車ではありませんが、完全に機能するオプションです。すべての通知、イベント、または何らかの何らかのループを何らかの形で実行するための駆動アクションが存在することに注意してください。2.フェラーリを修理することをお勧めします。
ジェイコブVlijm

1
@Rumesh $PATH ファイル拡張子使用してスクリプトを実行し、前述の言語で実行するのはそれほどエレガントなソリューションではありません。問題は、1人のユーザーに対して実行するか、すべてのユーザーに対して実行するかです。最後のケースでは、提案されたものとは別のセットアップが必要ですが、提案されているセットアップは望ましくありません:)。sleep 15十分ではないかもしれませんが、よりエレガントな解決策は、ブレーク「スマート」にしましょうスクリプトを試して/起動手順を実行するスクリプトのための「準備完了」になるまで起動する以外にすることであろう。少し追加する必要があります。お知らせ下さい。
ジェイコブVlijm

1
@Rumeshスクリプト$PATHは言語拡張機能を持たず、実行可能であるべきではないので、lintian.debian.org / tags / scriptpython3
Jacob Vlijm

1
@JacobVlijm以前に実行可能に設定していたので、使用できると思うconnect_screen
-Rumesh

2

これは、次の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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.