Search code examples
bashsyntax-errorunicode-string

']' expected Bash syntax error - despite `]` being present and surrounded by spaces


When running my bash script, I have the following error:

./myscript.sh:[:16: ']' expected

Line 16 is:

    [ -d "$dir" ] && echo "$dir" && for file in "$dir"/*/*

Usually the mistake comes from a missing space in the [] condition but I didn't forget it. Here is the rest of the script starting at line 14:

for dir in "$message_directory"/*
do
    [ -d "$dir" ] && echo "$dir" && for file in "$dir"/*/*
    do
        if [ -d "$file" ] ; then
            if [[ -f "$file"/Message.txt || -f "$file"/Message.html ]] ; then
                hashMD5=$(md5sum "$file/message"* | cut -d " " -f1 | head -n 1)
                todelete=$(find "$directory_to_check" -type f -not -path "*$message_directory*" -name "Message*" -exec md5sum "{}" \; | grep "^$hashMD5" )
                todelete=$(echo "$todelete" | tr -s " " | cut -d " " -f2-)
                todelete=$(echo "$todelete" | sed -E 's/(Message[0-9][0-9]*).+/\1/' )
                if [[ ! -z "$todelete" ]] ; then
                    echo "searching for hash : $hashMD5"
                    while read -r line; do
                        message_todelete=$(echo "$line")
                        echo "I will delete : $message_todelete"
                        md5sum "$todelete/Message"* | head -n 1
                        #rm -r "$line"
                    done <<< "$todelete"
                fi
            fi

        fi
    done
done

I tried to run the script with dash it worked until the <<< is met, which is understandable, but no error about the missing ]


Solution

  • Your error stems from the presence of Unicode whitespace (in the non-ASCII range) right after the closing ], specifically the NO-BREAK SPACE Unicode character (Unicode U+00A0).

    Bash doesn't recognize such whitespace, which is why it cannot find the closing ].[1]

    You can verify this as follows:

    LC_ALL=C cat -et myscript.sh
    

    reveals non-ASCII character as Meta-key combinations.
    The Unicode no-break spaces show as M-BM-.

    Incidentally, when SO renders your code in the question, these no-break spaces are converted to regular spaces, so copying & pasting your code does not reveal the problem - only inspecting the source code of your question does.


    If you want automated translation of non-ASCII whitespace and punctuation in UTF-8-encoded files to their closest ASCII equivalents, you can use my nws (white-space normalization) CLI; e.g.:
    nws --ascii -i.bak myscript.sh.
    nws can be installed via the npm registry by executing [sudo] npm install -g nws-cli, or manually from the repository.


    [1] [ and ] must be separated from surrounding elements by whitespace in order to be recognized as syntax elements by Bash. In this case, Bash saw word ]<no-break-space>, because the no-break space is not whitespace from Bash's perspective, and so no closing ] was found.