Ubuntu下Shell脚本if条件分支语法错误排查求助
修复你的Shell脚本语法错误
我来帮你排查下这个脚本里的语法问题,你遇到的报错主要是几个常见的Shell脚本规范没做好,尤其是elif的结构和条件语句的格式问题,咱们一步步来修正:
核心语法错误点
if/elif后必须分隔then:Shell要求条件表达式结束后,要么用分号;和then隔开,要么把then单独放一行。比如你写的if [ "$1" = "-a" -a $# -lt 3 ] then,正确写法是if [ "$1" = "-a" -a $# -lt 3 ]; then,你所有的if/elif都没做这个处理,这是最主要的语法问题。elif结构不完整:elif的格式是elif [ 条件 ]; then,你写的elif [ "$1" = "-s" -a $# -lt 4 ]后面直接接了嵌套if,没有加then,导致Shell无法识别分支结构,-c、-d、-n分支都有这个问题。- 注释符号用错了:Shell里单行注释是
#,你用了// syntax error,//会被当作命令执行,这直接触发了语法报错,得改成# syntax error或者删掉。 - 嵌套
if的fi闭合问题:每个if都需要对应的fi来收尾,你有些分支的fi位置不对,导致整个脚本逻辑结构混乱。
修正后的完整脚本
#!/bin/bash if [ "$1" = "-a" -a $# -lt 3 ]; then echo "Add a new line in katalogos!" read -p "Give me a name... " name read -p "Give me a surname... " surname read -p "Give me a city name... " cityName read -p "Give me a phone number... " num echo "$name $surname $cityName $num" > katalogos elif [ "$1" = "-l" -a $# -lt 3 ]; then echo "Content of katalogos will be sorted numerically and blank lines will be excluded!" sort -b -n katalogos elif [ "$1" = "-s" -a $# -lt 4 ]; then if [[ $2 != *[!0-9]* ]]; then echo "Content of katalogos will be sorted according to the second argument!" sort +$3 katalogos fi elif [ "$1" = "-c" -a $# -lt 4 ]; then # 修正了注释符号 if [[ $2 = *[!0-9]* ]]; then echo "Content of katalogos will be sorted according to the keyword!" if [ $(grep -e "$2" katalogos | wc -l) -eq 0 ]; then echo "String is not matched." else grep -e "$2" katalogos fi fi elif [ "$1" = "-d" -a ( "$3" = "-b" -o "$3" = "-r" ) ]; then if [[ $2 = *[!0-9]* ]]; then echo "Katalogos's string matching lines will be deleted and blank lines will be in their place, assuming that the third argument equals -b, else just the lines will be deleted!" if [ $(grep -e "$2" katalogos | wc -l) -eq 0 ]; then echo "String is not matched." else if [ "$3" = "-b" ]; then sed -i "/$2/d" katalogos && sed -i '$a ' katalogos # 修正了sed的语法错误 echo "A blank line inserted in place of the deleted one." else sed -i "/$2/d" katalogos # 修正了sed的语法错误 echo "Line deleted." fi fi fi elif [ "$1" = "-n" ]; then echo "katalogos's number of blank lines will be shown with the ability to delete them!" grep -cvP '\S' katalogos read -p "Do you want to delete them? Type 1 for yes or 0 for no... " ans if [ $ans -eq 1 ]; then sed -i '/^$/d' katalogos # 修正了删除空行的逻辑 echo "Lines deleted." fi else echo "Help centre!" echo "-Type ./telcat -a to insert a new line to katalogos." echo "-Type ./telcat -l to see the contents of katalogos sorted numerically (excluding blank lines)." echo "-Type ./telcat -s plus a number to see the contents of katalogos sorted by the data that the number points to." echo "-Type ./telcat -c plus a keyword to see only the lines that match with the word given." echo "-Type ./telcat -d plus a keyword and -b or -r to delete the lines that contain the word given. Specifically if the third argument is -b it will automatically add a blank line to the deleted one and if it is -r it will not." echo "-Type ./telcat -n to see the number of blank lines of katalogos." echo "End of help centre!" fi
额外的优化建议
- 尽量用
[[ ]]替代[ ],它支持更丰富的字符串匹配和逻辑表达式,可读性更强,比如可以把[ "$1" = "-a" -a $# -lt 3 ]改成[[ "$1" == "-a" && $# -lt 3 ]]。 - 参数引用尽量都加双引号,避免空格或特殊字符导致的错误,比如
grep -e "$2" katalogos这种写法是对的,不要漏了引号。 sort +$3是旧版语法,新版sort推荐用-k $3,比如sort -k $3 katalogos兼容性更好。
内容的提问来源于stack exchange,提问作者Marios Koni




