我正在尝试在Bash脚本中评估一个布尔变量,但它总是返回false。
以下是代码:
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
无论“找到设备”是否被执行,我总是进入if语句。当DEVICE_FOUND = true时,它不应该在最后一个if但是它会进入。
我不明白为什么会这样。
有人知道吗?
非常感谢。
答案 0 :(得分:7)
那是因为你在|
之后设置了真值,即在子shell中。子shell中的变量值不会传播回父shell。摆脱子shell:
while read line
do
...
done <<< "$tmp"
答案 1 :(得分:3)
问题不在于布尔值,而是while循环在管道中,因此在子shell中执行。更改子shell中的DEVICE_FOUND对主shell中的DEVICE_FOUND没有影响,它只是保持为false。如果你正在使用bash(即如果脚本开头的shebang是#!/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
答案 2 :(得分: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
答案 3 :(得分:0)
bash(以及任何符合POSIX的shell)中没有布尔类型。实际有效的是,您正在运行true
(退出成功状态,不一定是0
)或false
(退出失败0
语句中的em> status,不一定不是if
)外部命令。如果第一个列表的计算结果为if
,则0
语句将执行第二个列表。您可能遇到过这样的系统:true
或false
命令都不可用,或者它们的工作方式与预期不同。使用“整数”值(所有值都是内部字符串)或空/非空字符串值。
另外请注意:
adb devices | tail -n +2 | awk '{print $1}' | while read …
do
…
done