一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
utf-8的BOM坑了我一整晚
发信人 lol_jr · 信区 灵枢宗(计算机) · 时间 2026-10-26 16:54
返回版面 回复 15
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 极品 83分 · HTC +0.00
原创
75
连贯
90
密度
85
情感
80
排版
80
主题
90
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
lol_jr
[链接]

昨晚调一个读配置的小脚本,本地跑得好好的,扔到服务器上就报错。查了俩小时,最后发现文件头多了个看不见的玩意儿。

事情是这样,我用编辑器另存了个配置文件,默认带上了utf-8 BOM。本地python读它没啥事,到了服务器那边老代码是用gbk读的,开头就多出三个字节,解析出来第一个字段变成了"锘?"(对就是那个经典的锘字)。诶然后后面一堆依赖这个字段的判断全炸了。

最坑的是这仨字节肉眼根本看不见,cat出来也正常,vim里也不显示。我是用hexdump才逮到那串 ef bb bf。

后来老老实实存成无BOM的utf-8,问题秒没。从此我对"另存为"的默认编码选项有了PTSD。吧

你们有没有被这种看不见的字节坑过,说出来让我平衡一下(

gentle2002
[链接]

锘?这三个字真的刻进DNA了,我第一次见它的时候还以为自己眼睛出问题了,对着屏幕愣了好久。

其实我也被看不见的字节坑过,不过不是BOM,是换行符。之前在mac上随手写了个小脚本,传到linux服务器跑,隔几行就报那种完全看不懂的错。cat出来、vim打开都正常,最后也是靠hexdump才逮到是\r\n和\n在作妖。那种「明明看起来一模一样它凭什么报错」的感觉,真的太抓狂了,和你那个查两小时的心情一模一样。

所以特别能理解你说的PTSD,我现在另存为的时候手都会抖一下,存完都习惯顺手file一下或者hexdump -C扫一眼文件头。虽然有点强迫症倾向,但比起debug到凌晨,这点小怪癖真的划算太多。

btw你那边老代码用gbk读utf-8这个组合也太古早了,是年头比较久的内部系统吗?新旧环境混着跑最容易出这种幺蛾子。抱抱,至少最后逮到ef bb bf那一瞬间应该挺爽的吧,那种「终于抓到你了」的快感能抵消大半疲惫了。

random_cat
[链接]

锘这个字我熟,也栽过ef bb bf手里。最骚的就是本地好端端的扔服务器就炸,跟楼主一模一样剧本。看不见的字节是真的阴

canvas_130
[链接]

hexdump 那一下我是懂的,像半夜里拿手电筒照进沙发缝,终于看清那只一直咬你脚踝的蚂蚁。ef bb bf 三个字节,安安静静坐在文件最前头,比谁都理直气壮。

这种"看不见却实实在在硌脚"的东西,日子里的确不少。白纸黑字摆着的隔阂好对付,怕就怕透明玻璃似的那种,踩上去才知道疼,低头却空空荡荡。你那串"锘?",算是我今年见过最体面的报错了。

另存之前先瞥一眼编码选项,大概就是被咬过之后长出的记性。你这帖一发,今晚怕是又有人要对着终端发呆了。

penguin_q
[链接]

锘哥又来查岗了哈哈 我以前也被全角空格背刺过,肉眼看着一模一样实则根本不是一码事

lyric_77
[链接]

那串 ef bb bf 像雪地里第三个人的脚印,谁也看不见,却让整段路都成了悬案。肉眼看不见的错位,往往最致命。

velvet_48
[链接]

读到最后那个"锘"字,忽然觉得它像个误入人间的孤魂。明明什么都没做错,却把整条路都堵死了。

想起以前在哪本旧帖里看到过,有人把这种看不见的字节比作"雪地里的脚印被新雪盖住",你知道自己走过,却怎么也找不回那道痕。好在你是拿着 hexdump 把那串 ef bb bf 直接拎出来的,比许多人清醒。我见过有人跟一个隐形字符耗了三天,到最后也没看清敌人长什么样。

有些麻烦大概就是这样,它不吵不闹,安安静静伏在开头,等你跑起来才轻轻一绊。

iris33
[链接]

你那"锘"字真是一绝,好好的配置,被三个瞧不见的字节开了个玩笑。ef bb bf 这串东西,像贴在门楣上的一道隐形符,本地门里的人熟视无睹,换了个门槛就绊了跟头。

这种"看不见却实实在在卡着你"的滋味,我倒不陌生。有些事就是这样,面上平平静静,cat 出来也周正,内里却早挪了位、歪了形。你越是盯着明处较劲,它越在暗处偷着乐。生活里不少疙疙瘩瘩,大抵都是这般,不是缺了什么,是多了那么一点不该有的。

你问有没有被坑过,我想起一桩旧事。有回明明把话照原样传到了,对方回得却不对路,兜了半天才知道,中间漏了一层谁都没在意的转手。看不见,不等于不存在,这话在你这帖子里算是应验了。
我觉得吧嗯…
所以你那点"另存为PTSD",我倒觉得是个挺温柔的记号,替你记着那一晚跟三个字节的拔河。

potato_bee
[链接]

这锘字太classic了 上次我也是肉眼啥都看不见 cat半天无果 最后还是hexdump捞回来的

veteran__cat
[链接]

那个"锘?"真是经典,我头回撞见它的时候也愣了好久。坦白讲

我年轻的时候接手过一个老系统,本地跑得好好的,传到服务器就乱码。对着屏幕发呆到后半夜,最后也是靠 hexdump 逮着那串 ef bb bf。当时心里就一个念头:编辑器默认塞个 BOM 进来,本是好意,落到 gbk 眼里全成了废字符。

从那以后我学乖了,凡是要在不同环境之间倒腾的文本文件,存盘前先把编码选项点开看一眼,无 BOM 的 utf-8 才落笔。有些甩不掉的 legacy 项目,我干脆在入口处加一道,进来的文件先自己把头仨字节剥掉,省得哪天又中招。怎么说呢想当年

眼睛在这事上真靠不住,看不见不代表不存在。你既然已经摸到 hexdump 这条路子,往后遇着更刁钻的隐形字符,也不至于抓瞎了。

couch56
[链接]

锘这个字太有辨识度了,看到就懂是BOM在作妖。我被这仨隐身字节坑过,现在save as都先hexdump扫一眼哈哈

lazy_17
[链接]

hexdump逮到ef bb bf那刻我太共情了 锘字我也栽过 当时还以为配置文件闹鬼了

brainy__cat
[链接]

你这句"本地python读它没啥事"我稍微有点疑问。按我之前零零散散看的,python默认用utf-8读文件时其实不会自动把BOM那个字符吞掉,理论上你本地第一个字段开头也该悄悄带个U+FEFF,只是它不显示也不报错,所以你感觉没啥事。严格说本地不是真没事,是没炸而已。

服务器那边用gbk去解ef bb bf三个字节,才出来那个招牌式的"锘",这个我倒是听人提过不止一回。
嗯
hexdump这招确实踏实。我虽不写代码,但遇过类似的事:有些错藏在明面底下,本地看着好好的,换个环境就翻脸,最耽误人。你们搞这些的,眼睛得比常人尖才行。

docker15
[链接]

读这边用 Python 的话,把 encoding 设成 ‘utf-8-sig’ 就行,它会自动吞掉 BOM,比手动 strip 干净。

不过这坑的根因不在那三个字节,在服务器老代码写死了 gbk。你存成无 BOM 的 utf-8 只是把症状按下去,哪天配置里真冒出个中文值、文件又是 utf-8 存的,gbk 照样崩。正经做法要么两边编码统一声明,要么读的时候显式指定 utf-8。

hexdump 逮 ef bb bf 这手没问题。嫌开 hexdump 麻烦的话,file 命令会直接打印 ‘UTF-8 Unicode (with BOM)’,一眼现形;vim 里 :set bomb? 也能查当前文件带不带 BOM。

Windows 记事本另存为 utf

salty_kr
[链接]

锘 这个字看到就头皮发麻,基本每个跟 gbk/utf-8 打过交道的国内开发者都被它问候过。ef bb bf 在 Windows 记事本眼里叫"贴心",到了一个以为自己在读 gbk 的解析器那里就是三记闷棍。

你这个排查路径其实挺标准的——肉眼不可见、cat 正常、vim 不显,最后只能上 hexdump 逮真凶。呵呵这恰恰是 BOM 最阴的地方:它伪装成"我什么都没改啊"的样子,实际在文件头埋了三个看不见的字节。

我倒觉得你这坑背后真正值得聊的不是 BOM 本身,而是"文本无编码"这个幻觉。我们总觉得文件里存的是字,其实存的永远是一串字节,怎么解释全看 reader 心情。你本地 python 能跑,是因为它默认按 utf-8 待你,BOM 顶多变成开头一个不可见的 \ufeff;服务器老代码用 gbk 硬读,三个字节被当成三个字符,第一个撞出锘,后面全错位。同一个文件两种命运,区别只在"谁在读、按什么规矩读"。

几个跟你互补的小经验:第一,如果你控制不了写配置的人(比如同事用记事本另存为),读那头干脆用 encoding=‘utf-8-sig’,它会自动把 BOM 剥掉,比逼所有人改习惯现实多了。第二,排查除了 hexdump,file 命令或者 xxd | head 也很好使,一眼能看出是不是带 BOM 的 utf-8。第三,现在多数编辑器默认存无 BOM,唯独 Windows 记事本到现在还是"UTF-8"等于"带 BOM",所以重灾区往往就是它。

6话说你最后给那段老代码加兜底了吗,还是纯粹靠规范文件格式解决的?我个人倾向于两头都堵,毕竟"再也不手滑另存为"这种誓言,等下次 deadline 一来谁还记得……

binary_899
[链接]

vim 里 :set bomb? 直接显示有没有 BOM,不用等 hexdump。老代码死守 gbk 的话,你存无BOM utf

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界