开发者

Bash variable kills script execution

Sorry if this is better suited at serverfault, but I think it learns more towards the programming side of things.

I have some code that's going into /etc/rc.local to detect what type of touch screen monitor is plugged in and changes out the xorg.conf before launching X. Here is a small snippet:

CURRENT_MONITOR=`ls /dev/usb | grep 'egalax_touch\|quanta_touch'`
case $CURRENT_MONITOR 开发者_如何学Goin
'')
    CURRENT_MONITOR='none'
    ;;
esac

If one of those two touch screens is plugged in, it works just fine. If any other monitor is plugged in, it stops at the "CURRENT_MONITOR=ls /dev/usb | grep 'egalax_touch\|quanta_touch'."

For testing I touched two files. One before creating CURRENT_MONITOR and one after CURRENT_MONITOR and only file touched before is created.

I'm not a bash programmer so this might be something very obvious.


Edit: the answer below was not actually correct. The correct solution is in the comments: the script included set -e, so a failing command would terminate the script, and in the case where neither monitor was plugged in the grep would fail.


If CURRENT_MONITOR contains spaces, then your case statement will become (say)

case monitor1 monitor2 in

which is a syntax error. You need to quote the variable:

case "$CURRENT_MONITOR" in
'')
    CURRENT_MONITOR='none'
    ;;
esac


I believe quoting the variable will fix your problem:

case "$CURRENT_MONITOR" in

if the directory is empty, without the quotes that statement evaluates to:

case in

which is a syntax error and will cause your script to abort. Are you capturing stderr somewhere. If so, it's likely you'll see:

bash: syntax error near unexpected token `'''

Also, you should avoid parsing ls:

for i in /dev/usb/*
do
    case i in
        *egalax_touch*)
...

However, you don't show your complete case statement. If that's all you're doing with it, then why not:

if [[ -z $CURRENT_MONITOR ]]; then $CURRENT_MONITOR='none'; fi

or

[[ ${CURRENT_MONITOR:=none} ]]        # assigns a default if null or unset

or

: ${CURRENT_MONITOR:=none}


CURRENT_MONITOR=`ls /dev/usb | grep 'egalax_touch\|quanta_touch'` 
echo $CURRENT_MONITOR | od -xa > some_file
# This will let you see what is in the var that is failing, even if it has funky bytes in it.
# some_file could be /dev/console or you could pipe it into logger or you could use tee and do both
case $CURRENT_MONITOR in 
'') 
    CURRENT_MONITOR='none' 
    ;; 
esac 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜