Bash变量会导致脚本执行死亡

时间:2010-04-08 18:04:19

标签: bash

很抱歉,如果这更适合在serverfault,但我认为它更多地了解编程方面。

我有一些代码进入/etc/rc.local来检测插入了什么类型的触摸屏显示器,并在启动X之前更改了xorg.conf。这是一个小片段:

CURRENT_MONITOR=`ls /dev/usb | grep 'egalax_touch\|quanta_touch'`
case $CURRENT_MONITOR in
'')
    CURRENT_MONITOR='none'
    ;;
esac

如果插入了这两个触摸屏中的一个,它就可以正常工作。如果插入了任何其他显示器,它将停在“CURRENT_MONITOR = ls /dev/usb | grep 'egalax_touch\|quanta_touch'。”

为了测试我触摸了两个文件。一个在创建CURRENT_MONITOR之前,一个在CURRENT_MONITOR之后,只创建之前触及的文件。

我不是一个bash程序员,所以这可能是非常明显的。

3 个答案:

答案 0 :(得分:2)

编辑:下面的答案实际上并不正确。正确的解决方案在注释中:脚本包含set -e,因此失败的命令将终止脚本,并且在没有插入监视器的情况下,grep将失败。


如果CURRENT_MONITOR包含空格,那么您的case语句将变为(例如)

case monitor1 monitor2 in

这是一个语法错误。您需要引用变量:

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

答案 1 :(得分:1)

我相信引用该变量可以解决您的问题:

case "$CURRENT_MONITOR" in

如果目录为空,则没有语句求值为的引号:

case in

这是一个语法错误,会导致您的脚本中止。你在某处捕获stderr吗?如果是这样,你很可能会看到:

bash: syntax error near unexpected token `'''

此外,您应该避免parsing ls

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

但是,您没有显示完整的case声明。如果这就是你所做的一切,那么为什么不呢:

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

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

: ${CURRENT_MONITOR:=none}

答案 2 :(得分:0)

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