连接监视器时运行脚本


13

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所以我使用的规则可能是错误的。如果有人知道解决我的问题的适当规则,请留下答案。

我的显卡是英特尔GM965集成芯片组


您是否特别想要这样?一个很小的背景脚本将是小菜一碟。
Jacob Vlijm

@JacobVlijm脚本将如何?你能举个例子。
Rumesh 2015年

仅在连接了(任何)第二台显示器时才触发吗?
Jacob Vlijm

是的,当我连接第二台显示器时,我需要运行自己的脚本
Rumesh 2015年

1
没问题,请花点时间回答:)
Rumesh 2015年

Answers:


7

如果屏幕已连接或断开连接,则运行命令的另一种方法

另一种解决方案是运行一个很小的后台脚本。在后台运行下面的脚本,我无法衡量处理器负载的任何增加。

每当连接或断开第二个屏幕时,这是一种运行脚本或任何其他命令的简便方法。

示例脚本

  • 只需每五秒钟检查一次字符串“ connected”在命令输出中出现了多少次xrandr(请注意“ connected”后的空格以防止与“ disconnected”的错误匹配)。每次出现都代表一个连接的屏幕。
  • 如果出现次数发生变化,则说明屏幕已连接或已断开。该更改由脚本“通知”,并且可以连接到命令,您可以在脚本的开头部分进行设置。

剧本

#!/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. 在开头部分,将命令设置为在connect上运行(我将“ gedit”设置为示例,请注意引号)。同样,也可以在断开连接上设置命令。否则disconnect_command = ""就这样。

    如果确实使用了disconnect-命令,请取消注释该行:

    run_command(disconnect_command)

    并注释掉该行:

    pass

    如脚本所示

  3. 在终端上测试运行脚本,连接屏幕,看看一切是否正常。
  4. 如果一切正常,请将其添加到启动应用程序:Dash>启动应用程序>添加命令:

    /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
您是在给一辆快车损坏的人提供自行车,而不是修理汽车...
solsTiC15年

1
@solsTiCe 1.这不是自行车,而是功能完善的选择。请记住,所有以某种方式运行某种循环的通知,事件或任何驱动的动作都存在。2.我建议您再修理法拉利。
Jacob Vlijm

1
@Rumesh在运行脚本$PATH 文件扩展名,并前面的语言是一个不那么完美的解决方案。问题是您要为一个用户还是为所有用户运行它。在最后一种情况下,需要的不是建议的另一种设置,但最好不是您建议的:)。该sleep 15可能不够,但更优雅的解决方案是使断裂的“智能”,让脚本的try /除外启动,直到启动过程是“准备”的脚本运行。将是次要的补充。让我知道。
Jacob Vlijm 2015年

1
@Rumesh脚本$PATH不应具有语言扩展名,并且应是可执行的,因此请运行时不python3参见lintian.debian.org/tags/script-with-language-extension.html
Jacob Vlijm 2015年

1
@JacobVlijm我之前已经将其设置为可执行文件,所以我想我可以使用它connect_screen
Rumesh 2015年

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.