3 回答

TA貢獻1898條經(jīng)驗 獲得超8個贊
如果您$VARIABLE的字符串是包含空格或其他特殊字符的字符串,并且使用了一個方括號(這是test命令的快捷方式),則該字符串可能會拆分為多個單詞。這些每個都被視為一個單獨的參數(shù)。
因此,一個變量被分成許多參數(shù):
VARIABLE=$(/some/command);
# returns "hello world"
if [ $VARIABLE == 0 ]; then
# fails as if you wrote:
# if [ hello world == 0 ]
fi
對于放下包含空格或其他特殊字符的字符串的任何函數(shù)調(diào)用,也是如此。
容易修復(fù)
將變量輸出用雙引號引起來,強制其保留為一個字符串(因此為一個參數(shù))。例如,
VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
# some action
fi
就那么簡單。但是,如果您也不能保證變量不會是一個空字符串,或者除了空格以外就什么都不是的字符串,請?zhí)较旅娴摹耙舱堊⒁?..”。
或者,另一種解決方法是使用雙方括號(這是該new test命令的快捷方式)。
但是,它僅存在于bash(顯然是korn和zsh)中,因此可能與/bin/shetc 調(diào)用的默認shell不兼容。
這意味著在某些系統(tǒng)上,它可能可以在控制臺上運行,但在其他地方(例如從)調(diào)用時則不能cron,具體取決于所有配置方式。
它看起來像這樣:
VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
# some action
fi
如果您的命令包含這樣的雙方括號,并且您在日志中遇到錯誤,但可以從控制臺運行,請嘗試將換成[[此處建議的替代方法,或者確保運行腳本的任何東西都使用支持[[aka 的外殼new test。
還要提防[: unary operator expected錯誤
如果看到“參數(shù)太多”錯誤,則很可能是您從函數(shù)中獲得了一個字符串,該字符串的輸出不可預(yù)測。如果還可以獲取一個空字符串(或所有空白字符串),那么即使使用上述“快速修復(fù)”,也將其視為零參數(shù),并且將失敗[: unary operator expected
如果您習慣于其他語言,則這是相同的“陷阱”-您不希望變量的內(nèi)容在評估之前像這樣被有效地打印到代碼中。
這是一個防止[: too many arguments和[: unary operator expected錯誤的示例:如果輸出為空,則將其替換為默認值(在此示例中為0),并用雙引號引起來:
VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
# some action
fi
(此處,如果$ VARIABLE為0或為空,則將執(zhí)行該操作。自然地,如果需要不同的行為,則應(yīng)將0(默認值)更改為其他默認值)
最后說明:由于[是的快捷方式test,因此上述所有錯誤均適用test: too many arguments(并且也適用test: unary operator expected)

TA貢獻1794條經(jīng)驗 獲得超8個贊
剛剛碰到這個帖子,通過得到相同的錯誤,試圖測試兩個變量是否均為空(或非空)。事實證明這是一個復(fù)合比較-7.3。其他比較運算符-高級Bash腳本編寫指南;我想我應(yīng)該注意以下幾點:
我曾經(jīng)-e以為一開始它意味著“空”。但這意味著“文件存在”- -z用于測試空變量(字符串)
字符串變量需要加引號
對于復(fù)合邏輯與比較,可以:
使用兩個tests和&&它們:[ ... ] && [ ... ]
或-a單獨使用運算符test:[ ... -a ... ]
這是一個有效的命令(搜索目錄中的所有txt文件,并轉(zhuǎn)儲grep包含兩個單詞的文件):
find /usr/share/doc -name '*.txt' | while read file; do \
a1=$(grep -H "description" $file); \
a2=$(grep -H "changes" $file); \
[ ! -z "$a1" -a ! -z "$a2" ] && echo -e "$a1 \n $a2" ; \
done
編輯2013年8月12日:相關(guān)問題注釋:
請注意,當用classic test(單方括號[)檢查字符串是否相等時,“ is equal”運算符之間必須有一個空格,在這種情況下,它是一個“ equals” =符號(盡管兩個equals的符號==似乎被視為相等)運營商)。因此,這將失敗(無提示):
$ if [ "1"=="" ] ; then echo A; else echo B; fi
A
$ if [ "1"="" ] ; then echo A; else echo B; fi
A
$ if [ "1"="" ] && [ "1"="1" ] ; then echo A; else echo B; fi
A
$ if [ "1"=="" ] && [ "1"=="1" ] ; then echo A; else echo B; fi
A
...但是增加空間-一切看起來都不錯:
$ if [ "1" = "" ] ; then echo A; else echo B; fi
B
$ if [ "1" == "" ] ; then echo A; else echo B; fi
B
$ if [ "1" = "" -a "1" = "1" ] ; then echo A; else echo B; fi
B
$ if [ "1" == "" -a "1" == "1" ] ; then echo A; else echo B; fi
B
添加回答
舉報