2011-11-12 2 views
3

Я пытаюсь оценить логическую переменную в сценариях Bash, но всегда возвращает false.Bash scripting: переменная boolean не работает должным образом

Вот код:

DEVICE_FOUND=false 
tmp=`adb devices | tail -n+2 | awk '{print $1}'` 

echo "$tmp" | while read line 
do 
    if [ "$DEVICE_ID" = "$line" ] 
    then 
     echo "Found a device" 
     DEVICE_FOUND=true 
    fi 
done 

if ! $DEVICE_FOUND 
then 
    echo "ERROR: The device "$DEVICE_ID" is not connected" 
    exit 
fi 

ли или нет «Найденный устройство» запускается на выполнение или нет, я всегда иду в, если заявление. Когда DEVICE_FOUND = true, он не должен идти последним, если это произойдет.

Я не понимаю, почему это так.

Кто-нибудь, пожалуйста, знает?

спасибо.

ответ

7

Это потому, что вы устанавливаете истинное значение после |, то есть в субоболочке. Значения переменных из подоболочки не распространяются обратно на родительскую оболочку. Избавиться от субоболочки:

while read line 
do 
    ... 
done <<< "$tmp" 
+0

Большое спасибо! Это работает! – Jary

1

У Bash нет булевых переменных. Следовательно, DEVICE_FOUND=false присваивает строку false - $DEVICE_FOUND.

Вы можете получить обычную функциональность булевого флага, используя условие «пустая переменная» как ваше «ложное» и «непустая переменная» как ваше «истинное» (или наоборот), или иначе проверить произвольное значения. Пример:

DEVICE_FOUND="" 
tmp=`adb devices | tail -n+2 | awk '{print $1}'` 

echo "$tmp" | while read line 
do 
    if [ "$DEVICE_ID" = "$line" ] 
    then 
     echo "Found a device" 
     DEVICE_FOUND=true 
    fi 
done 

if [ ! "$DEVICE_FOUND" ] 
then 
    echo "ERROR: The device "$DEVICE_ID" is not connected" 
    exit 
fi 
+0

Большого спасибо.Странно, я все еще получаю эту ошибку! – Jary

+0

Обнаружено устройство ОШИБКА: Устройство HT91MLD00464 не подключено. – Jary

+0

'true' и' false' являются встроенными bash. Ваш код содержит ту же ошибку, что и исходная, см. Мой ответ. – choroba

0

Там нет логического типа в Баше (и любая POSIX-совместимая оболочка). Что эффективно происходит то, что вы работаете в true (выходы с успехом статуса, не обязательно 0) или false (выходит с отказом статуса, не обязательно не 0) внешних командами в if заявления. Оператор if выполняет второй список, если первый список оценивается как 0. Возможно, вы столкнулись с системой, в которой отсутствуют команды true или false или где они работают иначе, чем ожидалось. Используйте значения «integer» (все значения являются внутренними строками) или пустыми/непустыми строковыми значениями.

На стороне записки, подумайте:

adb devices | tail -n +2 | awk '{print $1}' | while read … 
do 
    … 
done 
+0

Подоболочка является более вероятным объяснением, почему это не удается (+1), но я оставлю свой ответ для дальнейших ссылок. – PointedEars

3

Проблема не булево, то, что цикл в то время как в трубопроводе, и поэтому выполняется в подоболочки. Изменение DEVICE_FOUND в подоболочке не влияет на DEVICE_FOUND в основной оболочке, оно просто остается ложным. Если вы используете Баш (то есть, если притон в начале скрипта #!/bin/bash, не #!/bin/sh), есть несколько способов устранить трубы:

while read line 
do 
    if [ "$DEVICE_ID" = "$line" ] 
    then 
     echo "Found a device" 
     DEVICE_FOUND=true 
    fi 
done < <(echo "$tmp") 

или:

while read line 
do 
    if [ "$DEVICE_ID" = "$line" ] 
    then 
     echo "Found a device" 
     DEVICE_FOUND=true 
    fi 
done <<<"$tmp" 

Но в данном случае есть лучший способ (при условии, $DEVICE_ID не имеют какие-либо регулярные выражения метасимволов):

if echo "$tmp" | grep -q "^$DEVICE_ID\$"; then 
    echo "Found a device" 
else 
    echo "ERROR: The device "$DEVICE_ID" is not connected" 
    exit 
fi 
Смежные вопросы