我的腳本語法有問題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"