']'预期Bash语法错误 - 尽管`]`存在且被空格包围

aze*_*aze 2 bash syntax-error unicode-string

运行我的bash脚本时,出现以下错误:

./myscript.sh:[:16: ']' expected
Run Code Online (Sandbox Code Playgroud)

第16行是:

    [ -d "$dir" ] && echo "$dir" && for file in "$dir"/*/*
Run Code Online (Sandbox Code Playgroud)

通常错误来自于[]条件中缺少的空间,但我没有忘记它.以下是从第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
Run Code Online (Sandbox Code Playgroud)

我尝试运行脚本,dash直到<<<满足,这是可以理解的,但没有关于丢失的错误]

mkl*_*nt0 5

您的错误源于关闭后立即存在Unicode空白(在非ASCII范围内)],特别是NO-BREAK SPACE Unicode字符(Unicode U + 00A0).

Bash无法识别这样的空格,这就是为什么它无法找到结束].[1]

您可以按如下方式验证:

LC_ALL=C cat -et myscript.sh
Run Code Online (Sandbox Code Playgroud)

将非ASCII字符显示为元组合键.
Unicode不间断空格显示为M-BM-.

顺便提一下,当SO 在问题中呈现代码时,这些不间断空格会转换为常规空格,因此复制和粘贴代码并不能解决问题 - 只检查问题的源代码.


如果您希望将UTF-8编码文件中的非ASCII空格和标点符号自动转换为最接近的ASCII等效项,则可以使用我的nws(空白区域标准化)CLI; 例如:
nws --ascii -i.bak myscript.sh.
nws可以通过执行或手动从存储库通过npm注册表安装.[sudo] npm install -g nws-cli


[1] [并且]必须通过空格与周围元素分开,以便被Bash识别为语法元素.在这种情况下,Bash看到了一句话]<no-break-space>,因为从Bash的角度看,不间断的空间不是空白,因此没有]找到关闭.