【问题标题】:Syntax error: word unexpected ( expecting "fi" )语法错误:单词意外(期待“fi”)
【发布时间】:2019-03-27 17:37:15
【问题描述】:

我试着做脚本:

#!/bin/bash
cat test.txt
echo "Write del if you want delete or write save if you want save"
read s1
echo "Which symbol"
read s2
if [ $s1 = "del" ]
then
sed -i "/^$s2/d"
cat test.txt
if [ $s1 = "save" ]
then
echo "saved"
else
echo "Error"
fi cat test.txt

我有错误 - 语法错误:单词意外(期待“fi”) 请帮忙!

【问题讨论】:

  • 将您的脚本粘贴到shellcheck.net 以检查语法错误。
  • 您有两个if,但只有一个fibash 预计您打开的每个if 都有一个fi;由于您的两个条件都是排他性的(如果另一个条件不正确,则一个不能为真),请考虑使用elif 而不是您的第二个if,这也可以解决问题。
  • 在声明 if [ $s1 = "del" ] 中,您的引号完全错误。从文体上讲,你可能应该引用两个论点(if [ "$1" = "del" ](虽然我一直不明白为什么引号的文体论点没有让你写if "[" "$1" "=" "del" "]";),但如果你要少用引号,它们是del 附近不需要,但$1 附近需要。IOW,您应该将其更改为if [ "$1" = del ]
  • 我投票结束这个问题,因为它基于一个简单的语法错误。

标签: bash shell command-line scripting sh


【解决方案1】:

if 块或循环内缩进代码有助于发现此类问题。每个if 都需要一个fi 来结束该块。缩进你的代码:

#!/bin/bash
cat test.txt
echo "Write del if you want delete or write save if you want save"
read s1
echo "Which symbol"
read s2

if [ $s1 = "del" ]
then
    sed -i "/^$s2/d"
    cat test.txt

    if [ $s1 = "save" ]
    then
        echo "saved"
    else
        echo "Error"
    fi cat test.txt

您可以看到初始块没有用它自己的fi 关闭。你还有一个古怪的cat 和你的fi 在同一条线上闲逛。那不应该在那里。取而代之的是:

#!/bin/bash
cat test.txt
echo "Write del if you want delete or write save if you want save"
read s1
echo "Which symbol"
read s2

if [ $s1 = "del" ]
then
    sed -i "/^$s2/d"
    cat test.txt

    if [ $s1 = "save" ]
    then
        echo "saved"
    else
        echo "Error"
    fi 
    cat test.txt
fi

不能保证它会做你想做的事,但它在语法上是正确的。

我会高度建议将其转储到 shellcheck.net 中,这样它就可以为您指明正确的方向。特别是在您的测试中缺少双引号可能会导致一些奇怪的行为。


根据@Aaron 的评论,您可能正在寻找类似以下内容:

#!/bin/bash
cat test.txt
echo "Write del if you want delete or write save if you want save"
read s1
echo "Which symbol"
read s2

if [ "$s1" = "del" ]; then
    sed -i "/^$s2/d" test.txt    
elif [ "$s1" = "save" ]; then
    echo "saved"
else
    echo "Error"
fi 

cat test.txt

【讨论】:

  • $s1 不能同时是 delsave,我猜 OP 想在那里使用 elif
  • @Aaron 完全同意。我在底部添加了脚本的编辑版本,我认为可能是 OP 所追求的。
【解决方案2】:

有几个问题。

首先,您必须替换以下行:

sed -i "/^$s2/d"
cat test.txt

通过

sed -i "/^$s2/d" test.txt

我猜你不想有 2 个 if/then 指令,而是一个 elsif 指令,所以你应该像这样修复你的脚本:

then
sed -i "/^$s2/d" test.txt
elif [ $s1 = "save" ]
then
echo "saved"

另外,作为改进,我建议:

  • 将文件名放在专用变量中,以提高可读性和可维护性
  • 触摸脚本开头的文件,以确保它存在(即使是空的)

最终,脚本将如下所示:

#!/bin/bash

filePath="test.txt"

[ ! -f "$filePath" ] && echo -e "ERROR: file $filePath not found. It is required for this script to work properly" >&2 && exit 1

cat "$filePath"
echo "Write del if you want delete or write save if you want save"
read s1
echo "Which symbol"
read s2

if [ "$s1" = "del" ]; then
  sed -i "/^$s2/d" "$filePath"
elif [ "$s1" = "save" ]; then
  echo "saved"
else
  echo "Error"
fi

cat "$filePath"

您可以看到 s1 在 'if' 中被引用以避免出现空格字符时出现问题。

【讨论】:

  • 整体答案很好,但我不太确定touch 的建议:在许多情况下,我宁愿脚本因错误而失败(sed 抱怨找不到文件)而不是表现得好像一切都很好,而它肯定没有达到我的预期。也许使用set -e 来避免比第一个错误运行得更远将有助于避免用户可能不会理解的一系列丑陋错误
  • 我同意,如果脚本需要该文件,您应该将触摸解决方案替换为:[! -f "$filePath" ] && echo -e "ERROR: file $filePath not found. It is required for this script to work" >&2 && exit 1 我相应地编辑了我的初始答案。
  • 是的,有一个不太可怕的错误的警卫条件更好:)
猜你喜欢
  • 2014-10-21
  • 1970-01-01
  • 2020-02-15
  • 2017-09-12
  • 1970-01-01
  • 2019-12-06
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多