Bash脚本中Hexdump处理Unicode字符不符合预期的原因排查
导致终端与Bash脚本执行echo -e "\u2022"结果不同的核心原因是Shell环境与echo命令实现的行为差异,具体分两种情况:
1. Shell解释器类型不同
如果你的脚本使用#!/bin/sh作为shebang开头,而系统中/bin/sh指向的是Dash、Ash这类严格遵循POSIX标准的Shell,这类Shell的echo命令(无论内置还是外部二进制)不支持通过-e解析\uXXXX格式的Unicode转义序列——它会把\u2022当成普通的文本字符串直接输出,所以hexdump会得到\、u、2、0、2、2对应的ASCII码(5c 75 32 30 32 32)。
而你在终端直接执行时,使用的是交互式Bash,它的内置echo命令扩展了POSIX标准,支持-e选项解析包括\uXXXX在内的转义序列,会把\u2022转换成对应的Unicode字符(•),对应UTF-8编码的e2 80 a2。
2. Bash的POSIX兼容模式触发
即使脚本用#!/bin/bash开头,若脚本执行时开启了POSIXLY_CORRECT环境变量,Bash会切换到POSIX兼容模式,此时内置的echo会忽略-e选项,不再解析任何转义序列,同样会直接输出\u2022原始字符串。
验证示例
终端交互式Bash执行(正常解析):
echo -e "\u2022" | hexdump -C00000000 e2 80 a2 0a
用Dash执行脚本(不解析转义):
创建脚本test.sh:#!/bin/sh echo -e "\u2022" | hexdump -C执行后输出:
00000000 5c 75 32 30 32 32 0a |\u2022.|
Bash开启POSIX模式执行:
POSIXLY_CORRECT=1 bash -c 'echo -e "\u2022" | hexdump -C'输出同样是未转义的原始字符串编码。
内容的提问来源于stack exchange,提问作者Giles Thompson

