acpi 및 udev 이벤트에 의해 호출되면 스크립트가 잘못 동작함

acpi 및 udev 이벤트에 의해 호출되면 스크립트가 잘못 동작함

/etc/acpi/events및 에 다음 파일이 있습니다 /etc/udev/rules.d.

  • /etc/acpi/events/lidclose

    # Pass all events to our one handler script
    event=button/lid
    action=/etc/acpi/monitors.sh
    
  • /etc/udev/rules.d/80-monitor.rules

    # change monitor settings when monitor is plugged in or o$
    ACTION=="change", SUBSYSTEM=="drm", HOTPLUG=="1", RUN+="/etc/acpi/monitors.sh"
    
  • 이제 (실행 가능하며 루트가 소유함)/etc/acpi/monitors.sh

    #!/bin/sh
    
    # default monitor is LVDS1
    STATE=internal
    INTERNAL=LVDS1
    EXTERNAL=HDMI3
    
    # functions to switch from LVDS1 to VGA and vice versa
    function internal {
        echo "Switching to internal"
        xrandr --output $EXTERNAL --off --output $INTERNAL --auto
        STATE=internal
    }
    function external {
        echo "Switching to external"
        xrandr --output $EXTERNAL --auto --output $INTERNAL --off
        STATE=external
    }
    function both {
        echo "Switching to both"
        xrandr --output $EXTERNAL --auto --right-of $INTERNAL --output $INTERNAL --auto --primary
        STATE=both
    }
    
    # functions to check if VGA is connected and in use
    function externalConnected {
        ! xrandr | grep "^$EXTERNAL" | grep disconnected >/dev/null
    }
    function lidOpen {
        ! cat /proc/acpi/button/lid/LID/state | grep closed >/dev/null
    }
    
    # actual script
    if ! [ $STATE == "both" ] && externalConnected && lidOpen
    then
        both
    fi
    
    if ! [ $STATE == "external" ] && externalConnected && ! lidOpen
    then
        external
    fi
    
    if ! [ $STATE == "internal" ] && ! externalConnected && lidOpen
    then
        internal
    fi
    

이제 루트와 사용자로서 스크립트를 테스트했는데 완벽하게 작동했습니다. 또한 echo bla > /home/me/test여기에 몇 가지 테스트 출력을 넣었고 by가 호출되면 출력이 생성 udev되어 acpid실행됩니다. 유일한 것은 아무 일도 일어나지 않았다는 것입니다 xrandr.

내가 무엇을 놓치고 있나요? 오류를 찾기 위해 스크립트 출력을 기록하려면 어떻게 해야 합니까?

답변1

내 질문에 댓글을 달아주신 분들의 도움으로 문제를 파악하고 스크립트에서 수정했습니다.

이제 노트북을 사용하여 자동 화면 전환을 수행하는 방법에 대한 업데이트된 루틴이 있습니다. acpid, kms 및 udev가 필요합니다.

acpi 및 udev에 대해 다음 규칙을 만듭니다.

/etc/acpi/events/lidclose

# Pass all events to our one handler script
event=button/lid
action=/etc/acpi/monitors.sh

/etc/udev/rules.d/80-monitor.rules

# change monitor settings when monitor is plugged in or o$
ACTION=="change", SUBSYSTEM=="drm", HOTPLUG=="1", RUN+="/etc/acpi/monitors.sh"

이제 /etc/acpi/monitors.sh를 생성하십시오.

#!/bin/sh

# specify the monitors to use
INTERNAL=LVDS1
EXTERNAL=HDMI3
USERNAME=oli

# set some variables needed to control the x server
export XAUTHORITY=/home/$USERNAME/.Xauthority
export DISPLAY=:0

# functions to switch from internal screen to external screen and vice versa or to use both screens together
function internal {
    echo "Switching to internal" >> /var/log/monitors.log
    xrandr --verbose --output $EXTERNAL --off --output $INTERNAL --auto >> /var/log/monitors.log 2>&1
}
function external {
    echo "Switching to external" >> /var/log/monitors.log
    xrandr --verbose --output $EXTERNAL --auto --output $INTERNAL --off >> /var/log/monitors.log 2>&1
}
function both {
    echo "Switching to both" >> /var/log/monitors.log
    xrandr --verbose --output $EXTERNAL --auto --right-of $INTERNAL --output $INTERNAL --auto --primary >> /var/log/monitors.log 2>&1
}

# functions to check if external monitor is connected and in use
function externalConnected {
    ! xrandr | grep "^$EXTERNAL" | grep disconnected >/dev/null
}
function lidOpen {
    ! cat /proc/acpi/button/lid/LID/state | grep closed >/dev/null
}

# actual script
if externalConnected && lidOpen
then
    both
fi

if externalConnected && ! lidOpen
then
    external
fi

if ! externalConnected && lidOpen
then
    internal
fi

그것이 효과가 있기를 바랍니다.

답변2

Janoliver의 솔루션거의 완벽하게 작동합니다. 작은 수정으로 마침내 내 시스템의 HOTPLUG 변수 문제가 해결되었습니다.

/etc/udev/rules.d/80-monitor.rules:

# change monitor settings when monitor is plugged in or off
ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/etc/acpi/monitors.sh"

즉, HOTPLUG로 변경합니다 ENV{HOTPLUG}.

관련 정보