Bash

if 語句中的 elif 條件

  • November 28, 2018

我有這個變數

start=$1;
end=$2;
sn=${#start}
en=${#end}

如果:

if ( [ $# -eq 2 ] )
then
elif ( [ $sn -ne 3 ] && [ -n "$(printf '%s\n' "$start" | sed 's/[0-9]//g') " ] );
then     
   echo "Incorrect format"
   exit 1
elif ( [ $en -ne 3 ] && [ -n "$(printf '%s\n' "$end" | sed 's/[0-9]//g') " ] );
then
   echo "Incorrect format"
   exit 1
else
   echo "Correct format"
   exit 1
fi

我在第一個 elif 時出乎意料,我想檢查使用者提供的參數,它們只能由 3 位數字組成。

if ( [ $# -eq 2 ] )
then
elif

正如傑夫的回答所說,第一個if條件是缺少命令部分。Bash 和 Dash 給出的錯誤消息有點模糊,看起來它們直接來自解析器,並且他們沒有費心在那裡添加更使用者友好的消息。

如果你不想在分支內做任何事情,你仍然需要在那裡添加一些命令。我建議true,它沒有做任何事情。

為了解決這個問題,shellcheck.net給出了更多觀察結果:

if ( [ $# -eq 2 ] )
  ^-- SC2233: Remove superfluous (..) around condition.

括號開始一個子shell,這在此處不是必需的(並且涉及額外的成本,例如在 Bash 中分叉一個子程序)。

... [ -n "$(printf '%s\n' "$start" | sed 's/[0-9]//g') " ] 
>>                                                    ^-- 
            SC2157: Argument to -n is always true due to literal strings.

您已經引用了命令替換,很好!但最後你有一個額外的空間。無論命令替換輸出什麼,參數 to-n永遠不會是空的,因為那個空間。

(它還說明了引用$snand $en,這將是謹慎的做法,但如果您知道IFS不包含任何數字,則不是真的有必要。)


也就是說,我不確定條件是否仍然完全正確。你說:

我想檢查使用者提供的參數,它們只能由 3 位數字組成。

但請注意,下面的測試僅擷取sn不是三的情況,此外還有除數字以外的其他字元,即它通過abcand 1234,並且只拒絕,比如abcd。你想要一個or條件,||,而不是and

if [ $sn -ne 3 ] && [ -n "$(printf '%s\n' "$start" | sed 's/[0-9]//g')" ]; then
   echo reject

或者您可以只使用case和模式匹配:

case "$start" in
   [0-9][0-9][0-9]) echo "'$start' is ok";;
   *) echo "'$start' is invalid"; exit 1;;
esac

引用自:https://unix.stackexchange.com/questions/484739