EOF bất ngờ trong khi tìm kiếm kết hợp `" '- tập lệnh bash


38

Tôi vừa viết một tập lệnh bash và luôn gặp lỗi EOF này.

Vì vậy, đây là kịch bản của tôi (chỉ hoạt động trên 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

Và đây là lỗi của tôi:

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

Câu trả lời:


31

Bạn có thể thấy vấn đề của bạn nếu bạn chỉ nhìn vào câu hỏi của bạn. Lưu ý cách tô sáng cú pháp được vặn lên sau dòng 95:

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

Như thông báo lỗi cho bạn biết, bạn có một thông tin chưa từng có ". Chỉ cần loại bỏ phần bổ sung "từ dòng trên và bạn sẽ ổn:

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

1
Kỳ lạ thay, tôi đã có cùng một vấn đề và đó là vì tôi có một sudo echo ""dòng .. Xóa 2 dấu ngoặc kép, để lại sudo echolàm cho nó hoạt động hoàn hảo.
vinzee

@vinzee tại sao bạn lại chạy echovới sudo? Điều đó nói rằng, những gì bạn mô tả không có nhiều ý nghĩa, phải có một cái gì đó khác đang diễn ra.
terdon

Tôi làm sudo echobởi vì tập lệnh sẽ cần sudosau này trong các lệnh nhưng tôi muốn người dùng nhập mật khẩu sớm, để tập lệnh không cần đầu vào của anh ấy nữa trong vài phút. Và đối với lỗi, tôi đã có lỗi tương tự như đã thấy ở đây, nhưng nó đã được giải quyết bằng cách xóa 2 dấu ngoặc kép. Không có gì khác xảy ra ..
vinzee

1
@vinzee bạn có thể muốn đọc Làm cách nào để chạy lệnh 'sudo' trong tập lệnh? . Đối với các trích dẫn, phải có một cái gì đó khác. Có thể bạn đã có một ký tự không in sau khi trích dẫn đã bị xóa với chúng. Hoặc có thể bạn có hai dấu nháy đơn và sau đó một đôi ( echo ''") hoặc một cái gì đó như thế, nhưng có phải là một cái gì đó từ echo ""là tốt.
terdon

Cảm ơn liên kết, bạn đã đúng. Chạy sudo echocảm thấy hơi kỳ lạ .. Và tôi sẽ thử lại cài đặt linux vào tối nay và quay lại nhận xét kết quả ở đây.
vinzee

3

Lỗi này có thể khó theo dõi trong các tình huống thực tế. Ở đây tôi cung cấp một giải pháp cho tình hình thế giới thực. Tôi sẽ sử dụng kịch bản của tôi làm ví dụ.

Tôi đã cập nhật kịch bản shell của tôi. Khi thực hiện nó tôi nhận được thông báo lỗi sau:

/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

Đây là dòng cuối cùng có một cặp dấu ngoặc kép.

Thông thường, tôi kiểm tra tập lệnh shell của mình mỗi lần tôi sửa đổi nó. Lần này, tôi đã đợi một ngày và quên mất nơi tôi đã sửa đổi. Vấn đề xảy ra ở bất cứ đâu trước dòng này (1508). Vấn đề là ngay cả tôi đã nhận xét dòng 1508

#elif [ "$project" ]; then

người thực thi shell vẫn nói dòng 1508 có sự cố.

Tiếp theo tôi tạo một bản sao của kịch bản shell gốc. Xóa một loạt các mã từ dưới cùng. Sau đó xác nhận mã của tôi bằng lệnh sau

bash -n mysbashscript

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

Bây giờ tập tin của tôi là 1/3 kích thước ban đầu. Tôi thấy ngay vấn đề:

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

Vì một số lý do, "bên trong {} chưa từng có của trình phân tích cú pháp shell. Đây là nơi trình phân tích cú pháp shell có thể được cải thiện hơn nữa.

Thuật toán nhanh nhất để tìm ra vấn đề, là xóa một nửa mã của bạn từ dưới lên, nếu lỗi cú pháp biến mất, thì đó là một nửa. Nếu lỗi cú pháp vẫn còn, vấn đề ở nửa trên.

Nếu vấn đề trong nửa sau, hoàn tác xóa. Lặp lại quá trình này. Bạn có thể thu hẹp kích thước nhỏ hơn để tìm nguồn gốc của vấn đề.

Khi xóa mã, bạn phải xóa toàn bộ phần mã. Ví dụ toàn bộ chức năng.

Bạn có thể sử dụng bash -n scriptname hoặc chỉ trực tiếp thực thi tập lệnh. Cả hai nên làm việc.


1
"Vì một số lý do," không khớp "bên trong {} không bị bắt bởi trình phân tích cú pháp shell." Có phải chỉ vì về mặt cú pháp, nó được khớp, trên dòng 1508? Tức là chuỗi được mở trên dòng 500 được đóng trên dòng 1508, và sau đó là một chuỗi khác chuỗi được mở vào ngày 1508 mà không bao giờ bị đóng.
philh

Tôi đã không điều tra hành vi trích dẫn của bash. Bash có thể có trích dẫn nhiều dòng "line1 \ nline2" Tôi nhớ trong shell bạn thực hiện trích dẫn nhiều dòng với << ENDORE. Có thể bây giờ bạn có thể trực tiếp sử dụng trích dẫn kép để trích dẫn nhiều dòng. Tính năng này làm cho việc gỡ lỗi thực sự khó khăn.
Kemin Zhou
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.