寻找匹配的“”“时出现意外的EOF-bash脚本


37

我只是写了一个bash脚本,并且总是收到这个EOF错误。

所以这是我的脚本(仅适用于OS X):

#!/bin/bash

#DEFINITIONS BEGIN
en_sq() {
    echo -e "Enabling smart quotes..."
    defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool true
    status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
            if [ "$status" = "1" ]
                then
                    echo -e "Success! Smart quotes are now enabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
di_sq() {
    echo -e "Disabling smart quotes..."
    defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
    status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
            if [ "$status" = "0" ]
                then
                    echo -e "Success! Smart quotes are now disabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
en_sd() {
    echo -e "Enabling smart dashes..."
    defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool true
    status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
            if [ "$status" = "1" ]
                then
                    echo -e "Success! Smart dashes are now enabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
di_sd() {
    echo -e "Enabling smart dashes..."
    defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
    status=$(defaults read NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool)
            if [ "$status" = "0" ]
                then
                    echo -e "Success! Smart dashes are now disabled."
                    SUCCESS="TRUE"
            else
                echo -e "Sorry, an error occured. Try again."
            fi
}
#DEFINITIONS END
#---------------

#BEGIN OF CODE with properties
#This is only terminated if the user entered properties (eg ./sqd.sh 1 1)
if [ "$1" = "1" ]
    then
        en_sq
    elif [ "$1" = "0" ]
        then
            di_sq
fi

if [ "$2" = "1" ]
    then
        en_sd
        #exit 0 if both, $1 and $2 are correct entered and processed.
        exit 0
    elif [ "$1" = "0" ]
        then
            di_sd
            #exit 0 if both, $1 and $2 are correct entered and processed.
            exit 0
fi
#END OF CODE with properties
#---------------------------


#BEGIN OF CODE without properties
#This is terminated if the user didn't enter two properties
echo -e "\n\n\n\n\nINFO: You can use this command as following: $0 x y, while x and y can be either 0 for false or 1 for true."
echo -e "x is for the smart quotes, y for the smart dashes."
sleep 1
echo -e " \n Reading preferences...\n"
status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
    then
        echo -e "Smart quotes are enabled."
    elif [ "$status" = "0" ]
    then
        echo -e "Smart quotes are disabled."

    else
        echo -e "Sorry, an error occured. You have to run this on OS X""
fi

status=$(defaults read NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool)
if [ "$status" = "1" ]
    then
        echo -e "Smart dashes are enabled."
    elif [ "$status" = "0" ]
    then
        echo -e "Smart dashes are disabled."

    else
        echo -e "Sorry, an error occured. You have to run this on OS X!"
fi

sleep 3
echo -e "\n\n You can now enable or disable smart quotes."

until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Enter e for enable or d for disable:"
read sq

if [ "$sq" = "e" ]
    then
        en_sq
    elif [ "$sq" = "d" ]
        then
            di_sq
    else
        echo -e "\n\n ERROR! Please enter e for enable or d for disable!"
fi
done
SUCCESS="FALSE"

echo -e "\n\n You can now enable or disable smart dashes."

until [ "$SUCCESS" = "TRUE" ]
do
echo -e "Enter e for enable or d for disable:"
read sq

if [ "$sd" = "e" ]
    then
        en_sd
    elif [ "$sd" = "d" ]
        then
            di_sd
    else
        echo -e "\n\n ERROR! Please enter e for enable or d for disable!"
fi
done

这是我的错误:

./coding.sh: line 144: unexpected EOF while looking for matching `"'
./coding.sh: line 147: syntax error: unexpected end of file

Answers:


31

如果您只是看问题,就可以看到您的问题。请注意在第95行之后如何突出显示语法高亮:

echo -e "Sorry, an error occurred. You have to run this on OS X""

如错误消息所示,您有一个不匹配的"。只需"从上面的行中删除多余的部分,就可以了:

echo -e "Sorry, an error occurred. You have to run this on OS X"

1
奇怪的是,我遇到了同样的问题,这是因为我有sudo echo ""一行。.删除2个双引号,留下sudo echo使它运行完美。
vinzee

@vinzee你为什么会echosudo?就是说,您所描述的没有多大意义,肯定还有其他事情正在发生。
terdon

我这样做sudo echo是因为该脚本sudo稍后将在命令中使用,但是我希望用户尽早输入密码,以便该脚本在几分钟内不再需要其输入。对于该错误,我遇到了与此处相同的错误,但是通过删除两个双引号解决了该错误。没有别的事..
vinzee

1
@vinzee,您可能想阅读如何在脚本中运行“ sudo”命令?。至于报价,肯定还有别的东西。例如,也许在用引号删除了引号之后,您有一个非印刷字符。或者,也许您有两个单引号,然后有一个双引号(echo ''")或类似的东西,但是一定可以因为echo ""还好。
terdon

感谢您的链接,您是对的。运行sudo echo感觉有点怪异。.今晚我将在Linux安装上再试一次,然后在这里评论结果。
vinzee

3

在实际情况下可能很难跟踪此错误。在这里,我为现实情况提供了一种解决方案。我将以我的脚本为例。

我更新了我的shell脚本。执行它时,出现以下错误消息:

/somepath/bin/myshellscript: line 1508: unexpected EOF while looking for matching `"'
/somepath/bin/myshellscript: line 1520: syntax error: unexpected end of file

line 1508 elif [ "$project" ]; then

这是最后一行带有双引号的行。

通常,每次修改外壳脚本时,我都会对其进行检查。这次,我等了一天,却忘记了修改的地方。该行之前的任何地方都发生了问题(1508)。问题是,即使我注释了第1508行

#elif [ "$project" ]; then

外壳执行程序仍然说第1508行有问题。

接下来,我复制了原始Shell脚本。从底部删除一大堆代码。然后使用以下命令验证我的代码

bash -n mysbashscript

mybashscript: line 515: unexpected EOF while looking for matching `"'
mybashscript: line 561: syntax error: unexpected end of file

现在我的文件是原始大小的1/3。我立即看到了问题:

497 prepare_alignment() {
498     local projdir=${1:?"did not give project directory"}
499     local samp=${2:?"did not give sample name"}
500     local merged=${3:?"must give merged bam file name} # here is the problem

由于某种原因,外壳解析器无法捕获{}内部不匹配的“”,这是可以进一步改进外壳解析器的地方。

找到问题的最快算法是从底部删除代码的一半,如果语法错误消失了,那么就在这一半。如果语法错误仍然存​​在,则问题在上半部分。

如果下半年出现问题,请撤消删除。重复此过程。您可以缩小到较小的尺寸以找到问题的根源。

删除代码时,必须删除整个代码部分。例如整个功能。

您可以使用bash -n脚本名,也可以直接执行脚本。两者都应该起作用。


1
“由于某种原因,shell解析器未捕获{}内部的不匹配。”仅仅是因为在语法上,它在行1508上匹配了吗?也就是说,在行5508上关闭了在行500上打开的字符串,然后在行1508上关闭了该字符串。字符串是在1508年打开的,从未关闭过
philh

我没有调查bash的引用行为。Bash可能会有多行引号“ line1 \ nline2”,我记得在shell中,您使用<< <<标记做了多行引号。现在可能的话,您可以直接使用双引号来引用多行。此功能使调试非常困难。
周克敏
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.