我的脚本语法有问题sh
。我为我的华硕路由器编写了一个脚本。该脚本完美运行。但我有这一行:
if [[ "$OldIP" && "$StartIP" != "$OldIP" ]]; then echo OK; fi
仅当和不同时,它才应该为 true (并执行echo OK
) 。该生产线有效,但我希望看到它的工作效率更高。这些变量包含有效的 IP 地址。$StartIP
$OldIP
在某些情况下,$OldIP
不会被分配任何内容(未初始化)。但是,如果$OldIP
不存在,这意味着它们在我的 shell 中不一样!
我不希望该行执行以下操作: if$OldIP
不存在 -> 测试它们是否不同 -> run echo OK
。
我确实希望该行的意思是:a)如果$OldIP
不存在->结束。加 b) 如果$OldIP
存在 -> 测试它们是否不同 -> 运行echo OK
。
所以,如果可能的话,我想以 "$OLDIP" &&
某种方式删除。这不是一个真正的问题;好奇想学习:)
有点(但它不起作用):
if [ [ "$OldIP" ] != "$StartIP" ]; then echo OK; fi
或者
if [ $OldIP != "$StartIP" ]; then echo OK; fi
这是我想要的,但在什么时候会抱怨旧IP为空(但工作正常)
尽管
if [ "$OldIP" != "$StartIP" ]; then echo OK; fi
有效但忽略了这一点旧IP是空的
答案1
严格来说,如果变量从未被赋值,或者已经被赋值,则该变量不存在unset
。以空字符串作为值的变量存在。
标准参数扩展将在存在时${variable+value}
替换字符串(不是未设置或为空)。这可以用来测试是否存在,如下所示:value
variable
if [ "${OldIP+x}" = "x" ] && [ "$OldIP" != "$StartIP" ]; then
# code
fi
要测试OldIP
中是否存在bash
,请使用-v
测试:
if [[ -v OldIP ]] && [[ "$OldIP" != "$StartIP" ]]; then
# code
fi
仅当之前已设置(即使它设置为空字符串)时,才会在$OldIP
和之间执行字符串比较。请注意,测试采用$StartIP
OldIP
-v
姓名变量的。
答案2
我认为你的脚本非常有效。您当然不会在这方面花费很多周期。
另一种编写逻辑的方法:
{ test -n "$OldIP" || test "$StartIP" != "$OldIP"; } && echo OK
这表示“如果设置了 OldIP 或者 OldIP 和 StartIP 不同,则回显 OK。
请记住,这是您可以使用 阅读的[
另一个名称。test(1)
man 1 test
编辑:正如 Gilles 指出的那样,请注意避免( ... )
在不需要的地方创建子 shell。
{ ... ; }
可用于对命令进行分组,而无需执行新的 shell。
简要参考:http://www.gnu.org/software/bash/manual/html_node/Command-Grouping.html
答案3
这符合您的要求:
[ "${OldIP:-"$StartIP"}" != "$StartIP" ] && echo "OK"
同样如此(更复杂):
${OldIP:+false} || { [[ $OldIP != $StartIP ]] && echo "OK"; }
答案4
如果您使用bash
,则可以使用默认替换:
[[ "${OldIP:=oldunset}" != "${StartIP?StartUnset" ]] && echo "OK"
如果变量未设置或为 null,则语法${var:-def}
将计算为 的当前值$var
或指定的默认值(在本例中为)。def
变量的值(如果有)不变。
该语法${var?message}
将退出,错误代码为 1,并显示一条消息message
if $var
is unset or null。
如果您明确需要test
兼容测试,您可以这样做:
[ ! -z "$OldIP" -a "$OldIP" != "$StartIP" ] && echo "OK"