nieoczekiwany EOF podczas wyszukiwania pasującego skryptu bash


38

Właśnie napisałem skrypt bashowy i zawsze otrzymuję ten błąd EOF.

Oto mój skrypt (działa tylko w systemie 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

A oto mój błąd:

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

Odpowiedzi:


31

Możesz zobaczyć swój problem, jeśli spojrzysz na swoje pytanie. Zwróć uwagę, jak podświetlanie składni jest pomieszane po wierszu 95:

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

Jak mówi komunikat o błędzie, masz niedopasowane ". Po prostu usuń dodatkowe "z powyższej linii i wszystko powinno być w porządku:

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

1
O dziwo, miałem ten sam problem i to dlatego, że miałem sudo echo ""linię. Usunięcie dwóch podwójnych cudzysłowów, pozostawienie sudo echosprawia, że ​​działa idealnie.
vinzee

@vinzee dlaczego byś kiedykolwiek uruchomić echoz sudo? To powiedziawszy, to, co opisujesz, nie ma większego sensu, musiało być coś innego.
terdon

Robię to, sudo echoponieważ skrypt będzie potrzebował sudopóźniej poleceń, ale chcę, aby użytkownik wcześniej wprowadził swoje hasło, aby skrypt nie potrzebował więcej danych wejściowych przez kilka minut. Jeśli chodzi o błąd, miałem taki sam błąd, jak tutaj, ale został rozwiązany przez usunięcie 2 podwójnych cudzysłowów. Nic innego się nie wydarzyło
vinzee,

1
@vinzee możesz przeczytać Jak uruchomić polecenie „sudo” w skrypcie? . Co do cytatów, musiało być coś jeszcze. Może na przykład po cytatach, które zostały z nimi usunięte, miałeś znak niedrukowalny. A może miałeś dwa pojedyncze cytaty, a następnie podwójny ( echo ''") lub coś w tym rodzaju, ale musiało być coś, ponieważ echo ""jest w porządku.
terdon

Dzięki za link, masz rację. Bieganie sudo echowydawało mi się trochę dziwne ... I spróbuję jeszcze dziś wieczorem na mojej instalacji linuksowej i wrócę do komentowania wyników.
vinzee

3

Ten błąd może być trudny do wyśledzenia w rzeczywistych sytuacjach. Tutaj zapewniam jedno rozwiązanie dla rzeczywistej sytuacji na świecie. Użyję mojego skryptu jako przykładu.

Zaktualizowałem swój skrypt powłoki. Podczas jego wykonywania otrzymałem następujący komunikat o błędzie:

/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

To ostatni wiersz, który zawiera parę podwójnych cudzysłowów.

Zwykle sprawdzam skrypt powłoki za każdym razem, gdy go modyfikuję. Tym razem czekałem na jeden dzień i zapomniałem, gdzie dokonałem modyfikacji. Problem pojawił się gdziekolwiek przed tą linią (1508). Problem w tym, że nawet ja skomentowałem linię 1508

#elif [ "$project" ]; then

wykonawca powłoki nadal powiedział, że linia 1508 ma problemy.

Następnie zrobiłem kopię oryginalnego skryptu powłoki. Usuwanie całej wiązki kodu z dołu. Następnie sprawdź poprawność mojego kodu za pomocą następującego polecenia

bash -n mysbashscript

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

Teraz mój plik ma 1/3 oryginalnego rozmiaru. Natychmiast zobaczyłem problem:

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

Z jakiegoś powodu niedopasowane „wewnątrz {} nie jest przechwytywane przez analizator powłoki. To właśnie tam można dalej poprawić analizator powłoki.

Najszybszym algorytmem do znalezienia problemu jest usunięcie połowy kodu z dołu, jeśli błąd składniowy zniknie, znajdzie się on w tej połowie. Jeśli błąd składniowy nadal występuje, problem występuje w górnej połowie.

Jeśli problem wystąpi w późniejszej połowie, cofnij usuwanie. Powtórz ten proces. Możesz zawęzić rozmiar do mniejszego rozmiaru, aby znaleźć źródło problemu.

Usuwając kod, musisz usunąć całą sekcję kodu. Na przykład cała funkcja.

Możesz albo użyć bash -n nazwa skryptu, albo po prostu bezpośrednio wykonać skrypt. Oba powinny działać.


1
„Z jakiegoś powodu niedopasowane” wewnątrz {} nie jest przechwytywane przez analizator powłoki. „Czy to tylko dlatego, że pod względem składniowym jest on dopasowywany w linii 1508? ciąg jest otwierany na 1508, który nigdy się nie zamyka
phil

Nie badałem cytowania zachowania bash. Bash może mieć wielowierszowy cytat „line1 \ nline2”. Pamiętam, że w powłoce robisz wieloliniowy cytat z << ENDMARK. Być może teraz możesz bezpośrednio użyć podwójnego cudzysłowu, aby zacytować wiele wierszy. Ta funkcja naprawdę utrudnia debugowanie.
Kemin Zhou,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.