You are not logged in.
Pages: 1
Hi guys,
I'm having trouble with a condition in bash and I'd really appreciate some suggestions.
The relevant part of my script:
HDMI2=$(xrandr | grep HDMI2)
case "$HDMI2" in
"HDMI2 connected ("*) xrandr --output LVDS1 --off --output HDMI2 --auto
sh $USERHOME/.wallpaper &;;
"HDMI2 disconnected"*) (sleep 2 && xrandr --output LVDS1 --off --output HDMI2 --auto
sleep 3 && xrandr --output LVDS1 --off --output HDMI2 --auto && sh $USERHOME/.wallpaper
sleep 7 && xrandr --output LVDS1 --off --output HDMI2 --auto && sh $USERHOME/.wallpaper)&;;
*);;
esacThis is part of a script that gets called whenever my laptop is plugged into the docking station. It changes the output screen from the laptops display to my bigger external monitor.
Now, the external monitor isn't always recognized immediately. Sometimes there's a delay of 3 - 12 seconds so that HDMI2 reads as "HDMI2 disconnected" during that time.
As a workaround I've added the "HDMI2 disconnected"-part and made it try changing the screen again 2, 5 and 12 seconds after the initial try.
It works but it's not pretty and it makes my screen flash three times.
To stop the chain of xrandr when the command succeeds in changing the output I tried to introduce conditions like the following:
EXTOFF=$(xrandr | grep 'HDMI2 disconnected' | wc -l)
[...](sleep 2 && xrandr --...
sleep 3 && [ $EXTOFF = 1 ] && xrandr...
sleep 7 && [ $EXTOFF = 1 ] && xrandr...)&I've tried many variations, with or without ampersand, with case and if statements but the xrandr command always gets executed three times.
Long story short the screen still flashes and i can't figure out a better solution. I'm hoping you have some ideas.
Regards,
demian
P.S.:
Here's the whole script: http://pastebin.com/Rbh7gR3A
Last edited by demian (2010-05-20 03:12:34)
no place like /home
github
Offline
I think that your condition is wrong. But this can be a bashism... What about this
while [[ $(xrandr|grep -c "HDMI2 disconnected") != 0 ]]; do xrandr; sleep 2 ;doneLast edited by kazuo (2010-05-20 03:57:46)
Offline
Hi demian,
in the first line of your second code snippet you evaluate the result of the xrandr call and store it in the variable EXTOFF. In your subsequent lines you just re-check that value, but I believe what you intended is to get the xrandr result re-evaluated at that time.
Try this:
In your first line: EXTOFF="xrandr | grep 'HDMI2 disconnected' | wc -l"
In the following lines use eval $EXTOFF instead of just $EXTOFF
Hope this helps.
Offline
You're both right, thank you for your suggestions.
My condition was ill-thought-out and i needed to reevaluate it every time.
If the display stays disconnected i don't want an infinite while do loop in the background so now I'm using the following:
EXTON="xrandr | grep -c 'HDMI2 connected ('"
EXTOFF="xrandr | grep -c 'HDMI2 disconnected'"
(sleep 1 && [ $(eval $EXTON) = 1 ] && xrandr --output LVDS1 --off --output HDMI2 --auto && sh $USERHOME/.wallpaper && $verbose && logger "HDMI2: succeeded at 1st try" && echo >> $LOG
sleep 1 && [ $(eval $EXTON) = 1 ] && xrandr --output LVDS1 --off --output HDMI2 --auto && sh $USERHOME/.wallpaper && $verbose && logger "HDMI2: succeeded at 2nd try" && echo >> $LOG
sleep 3 && [ $(eval $EXTON) = 1 ] && xrandr --output LVDS1 --off --output HDMI2 --auto && sh $USERHOME/.wallpaper && $verbose && logger "HDMI2: succeeded at 3rd try" && echo >> $LOG
sleep 3 && [ $(eval $EXTON) = 1 ] && xrandr --output LVDS1 --off --output HDMI2 --auto && sh $USERHOME/.wallpaper && $verbose && logger "HDMI2: succeeded at 4th try" && echo >> $LOG
sleep 4 && [ $(eval $EXTON) = 1 ] && xrandr --output LVDS1 --off --output HDMI2 --auto && sh $USERHOME/.wallpaper && $verbose && logger "HDMI2: succeeded at 5th try" && echo >> $LOG
sleep 12 && [ $(eval $EXTON) = 1 ] && xrandr --output LVDS1 --off --output HDMI2 --auto && sh $USERHOME/.wallpaper && $verbose && logger "HDMI2: succeeded at 6th try" && echo >> $LOG
sleep 1 && [ $(eval $EXTOFF) = 1] && logger "HDMI2: failed to activate" && echo >> $LOG) &;;I can't say it's pretty but it does exactly what i want it to so thanks again.
Regards,
demian
no place like /home
github
Offline
Something like this might be a bit cleaner (note: untested, but I think it'll work) - not entirely sure what $verbose is so I took a guess ![]()
EXTON="xrandr | grep -c 'HDMI2 connected ('"
EXTOFF="xrandr | grep -c 'HDMI2 disconnected'"
for $((i=0; i<10; i++)); do
sleep 1
if [ $(eval $EXTON) = 1 ]; then
xrandr --output LVDS1 --off --output HDMI2 --auto
sh $USERHOME/.wallpaper
if [ -n "$verbose" ]; then
logger "HDMI2: succeeded at try number $i"
echo >> $LOG
fi
break
fi
done
if [ $(eval $EXTOFF) = 1 -a -n "$verbose"]; then
logger "HDMI2: failed to activate"
echo >> $LOG
fiOffline
line 39: `$((i=0; i<10; i++))': not a valid identifierI'm looking into three-expression loops now but i wouldn't mind if anyone could tip me to the solution
.
duh, i just had to remove the $ in front of the ((.
Code now looks like this:
$verbose && logger "switching monitor"
case "$HDMI2" in
"HDMI2 connected ("*) $verbose && logger "-> switching to HDMI2"
xrandr --output LVDS1 --off --output HDMI2 --auto
sh $USERHOME/.wallpaper &;;
"HDMI2 disconnected"*) $verbose && logger "-> HDMI2 not connected"
$verbose && logger "-> retrying every second for the next 20 seconds"
(for ((i=0; i<=20; i++));do
sleep 1
if [ $(eval $EXTON) = 1 ]; then
xrandr --output LVDS1 --off --output HDMI2 --auto
$verbose && logger "HDMI2: succeeded at try number $i"
echo >> $LOG
break
fi
done
if [ $(eval $EXTOFF) = 0 ]; then
sh $USERHOME/.wallpaper
$verbose && logger "restarting conky"
su -c "killall conky" $USER
LANG=en_US.UTF-8 su -c "conky -q -c $USERHOME/.conkydock &" $USER &
else
logger "HDMI2: failed to activate"
echo >> $LOG
fi) &;;
"HDMI2 connected 1"*) $verbose && logger "-> HDMI2 already active";;
*) $verbose && logger "-> undefined display state";;
esacThank you very much.
P.S.:
[[ "$1" = '-v' ]] && verbose=true || verbose=false
Last edited by demian (2010-05-21 17:35:32)
no place like /home
github
Offline
remove the dollar sign
for ((i=0; i<10; i++)); dois proper bash syntax as far as i can tell. just a typo on cerebral's part methinks.
/edit:
no offense to cerebral, but i prefer function calls to the eval syntax. i think it makes more sense and reads intuitively.
# these will return 0 or 1 for success/failure of the grep
ext_on() { xrandr | grep -Fq 'HDMI2 connected'; }
ext_off() { xrandr | grep -Fq 'HDMI2 disconnected'; }
do_on_work() {
# put here all things you want run when connected
}
do_off_work() {
# put here all things you want run when not connected
}
for ((i=0; i<20; i++)); do
if ext_on; then
do_on_work
break;
fi
done
ext_off && do_off_workjust another way to skin the cat
. (also, untested).
Last edited by brisbin33 (2010-05-21 18:09:26)
//github/
Offline
yeah, thanks, i figured it out, too. wasn't that hard, after all ![]()
btw, i recently stumbled over your scripts and found them to be a nice source to improve my bash a little. i'm using some of them too, like updatehosts or goodsong. Just wanted to say thanks for sharing them.
Regards,
demian
P.S.: I totally forgot to mention that i'm using wifi-pipe, your openbox pipe menu for wireless connection via netcfg. It's awesome!
Last edited by demian (2010-05-21 17:46:52)
no place like /home
github
Offline
btw, i recently stumbled over your scripts and found them to be a nice source to improve my bash a little. i'm using some of them too, like updatehosts or goodsong. Just wanted to say thanks for sharing them.
thank you!
//github/
Offline
remove the dollar sign. just a typo on cerebral's part methinks.
Damn, yeah. I missed that.
S'what I get for not running it through bash once or twice to weed out the obvious bugs
no offense to cerebral, but i prefer function calls to the eval syntax. i think it makes more sense and reads intuitively.
Agreed - the eval syntax wasn't my idea in the first place, I just didn't bother cleaning it up.
Offline
Pages: 1