Udev

腳本在被 acpi 和 udev 事件呼叫時行為不正常

  • November 21, 2018

/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"
  • 現在,(可執行並由root擁有)/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

現在,我以 root 和我的使用者身份測試了該腳本,它就像一個魅力。我還在其中放置了一些測試輸出echo bla > /home/me/test,當被呼叫udevacpid生成輸出時,它會被執行。唯一的事情是,沒有任何事情發生xrandr

我錯過了什麼?如何記錄腳本的輸出以查找錯誤?

在對我的問題發表評論的人的幫助下,我找出了問題所在並在腳本中修復了它。

現在這裡更新瞭如何使用筆記型電腦進行自動螢幕切換的常式。您需要 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

希望它會奏效。

引用自:https://unix.stackexchange.com/questions/14000