我的主计算机是一台笔记本电脑,我在Arch上运行i3wm。因此,我的监视器情况有时会发生变化,所以我想编写一个脚本,根据监视器连接到系统的情况来配置我的监视器。脚本在i3wm启动时运行。
至于显示器,有时我可能没有连接外部显示器,有时可能连接HDMI和DP显示器,有时我可能在另一个位置连接HDMI和DP显示器,但DP显示为不同的输出。
监测器如下:
守则如下:
#!/usr/bin/env bash
# The xRandR names of my monitors, including the internal laptop monitor / display
readonly MON_INTERNAL='eDP-1'
readonly MON1='DP-1'
readonly MON1_FALLBACK='DP-1-8'
readonly MON2='HDMI-2'
# The resolutiond of the given xRandR monitors / displays. NOTE: $MON1 and $MON1_FALLBACK are the same display, so only one res is needed
readonly MON_INTERNAL_RES='1920x1080'
readonly MON1_RES='2560x1440'
readonly MON2_RES='1680x1050'
main_mon=''
sec_mon=''
# Store a count of how many monitors are connected
mon_count=$(xrandr -q | grep -w 'connected' | wc -l)
# Configure the monitors via xRandR
config_monitors() {
if [[ "$#" -eq "2" ]]; then
xrandr --output $1 --primary --mode $2 --rotate normal --pos 0x0
elif [[ "$#" -eq "4" ]]; then
xrandr --output $MON_INTERNAL --off --output $1 --mode $2 --pos 1680x0 --right-of $3 --output $3 --mode $4 --pos 0x0 --left-of $1
fi
}
# Determine which main monitor is available
if [[ $mon_count -gt 1 ]]; then
# The name of which main monitor is connected (either $MON1 or $MON1_FALLBACK)
main_mon=$(xrandr -q | grep -w 'connected'| grep "^$MON1\|^$MON1_FALLBACK" | awk '{ print $1 }')
else # fallback to laptop display $MON_INTERNAL because the hardcoded displays aren't connected
main_mon=$MON_INTERNAL
fi
# Determine whether the secondary HDMI monitor, $MON2 is connected
if [[ $mon_count -gt 1 ]] && [[ $(xrandr -q | grep $MON2 | awk '{ print $2 }') -eq connected ]]; then
sec_mon=$MON2
fi
# Configure both external monitors if they're set or use the internal display
# TODO: Actual fallback logic for when HDMI display is connected but not the primary DP-x..
if [[ -n $main_mon ]] && [[ -n $sec_mon ]]; then
config_monitors "$main_mon" "$MON1_RES" "$sec_mon" "$MON2_RES"
else
config_monitors "$MON_INTERNAL" "$MON_INTERNAL_RES"
fi任何关于如何改进这个脚本的功能和/或可读性的建议都会受到极大的赞赏。这是我第一次真正地尝试编写一个实际服务于我的实际用途的Bash脚本。
发布于 2018-12-25 12:06:57
对于这样的问题,它有助于分解可能的状态,并为每个状态映射您想要做的事情,然后构建一个数据模型,使复制最小化。
以下是我对你问题的处理方法:
__
#!/usr/bin/env bash
# each PRIORITY entry must have matching entry in MODE; $displays will be sorted in priority order
declare -ar PRIORITY=( "DP-1*" HDMI-2 eDP-1 )
declare -Ar MODE=(
[eDP-1]=1920x1080
[DP-1*]=2560x1440
[HDMI-2]=1680x1050
)
# options corresponding to each possible config. sorted in PRIORITY order.
# left hand side is matched against space-separated list of actual monitor labels from xrandr
# template values like are zero-based
declare -Ar OPTS=(
[DP-1* HDMI-2 eDP-1]='--output --off --output --mode --pos 1680x0 --right-of --output --mode --pos 0x0 --left-of '
[HDMI-2 eDP-1]='--output --off --output --mode --pos 0x0'
[eDP-1*]='--output --primary --mode --rotate normal --pos 0x0'
)
declare -ar ALL_CONNECTED=( $( { xrandr -q || exit 1; } | awk '$2 == "connected" {print $1}' ) )
[[ ${#ALL_CONNECTED[@]} = 0 ]] && {
echo no monitors connected
exit 1
}
declare -a displays=()
declare -a modes=()
# populate displays and modes in preference order from ALL_CONNECTED
for (( i=0; i<${#PRIORITY[@]}; i++ )); do
for (( j=0; j<${#ALL_CONNECTED[@]}; j++ )); do
if [[ ${ALL_CONNECTED[$j]} == ${PRIORITY[$i]} ]]; then
displays+=( ${ALL_CONNECTED[$j]} )
modes+=( ${MODE[${PRIORITY[$i]}]} )
break
fi
done
done
echo "
ALL_CONNECTED: ${ALL_CONNECTED[@]}
displays: ${displays[@]}
modes: ${modes[@]}
"
for i in "${!OPTS[@]}"; do
if [[ "${displays[@]}" == $i ]]; then
opts=${OPTS[$i]}
opts=${opts///\]\}}
set -x
xrandr $( eval echo $opts )
exit $?
fi
done
echo "no OPT setting found for connected display combination of ${ALL_CONNECTED[@]} [ ${displays[@]} ]"
exit 1https://codereview.stackexchange.com/questions/208466
复制相似问题