一个活了 45 年的「愚蠢」 Bug!
转自:CSDN,翻译:弯月
英文:threadreaderapp
【CSDN编者按】微软于近期推出了Windows 10操作系统。不断压缩的更新周期下,一般而言,系统Bug的存活希望会被很快掐灭,快速迭代。但是本文的作者在Windows 10上从一个USB 3.0 SSD向另一个SSD拷贝文件时却遭遇了一个44年前的bug,他把这个“愚蠢”的Bug分享到了博客上,并且引起了开发者们的回忆热潮。
以下为译文:
现在都2018年了,而这个来自于1974年的错误信息居然还在。最新版本的Windows 10依然有这个限制,而这个bug第一次出现的时候星球大战还没上映,都跟水门事件一样老了。
这个bug出现时,超市里的东西还没有UPC条码,因为UPC还没发明。
这个bug出现时,世界上只有一家电话公司,因为他们还没分家。Ted Bundy还没被抓。Babe Ruth的本垒打纪录还没有被打破。
这个bug出现时,幸运大转轮还没播出,也没人看过Rocky Horror。斯皮尔伯格只是一系列小众电视剧的导演,电影票房也十分糟糕。埃德蒙德·费兹杰罗号货轮还是一堆铁矿石。
这个愚蠢的bug出现时,教父2才刚刚在电影院中上映。
1、那么,这个bug究竟是什么?
因为Unix(当时才仅仅5岁)发明了一个很好的点子——“一切皆是文件”,也就是说,你可以用同样的命令和指令读写套接字、管道、控制台等等。
这个点子是由Gary Kildall在1974年想出来的。用这个方法有很多方便之处,比如可以从串口拷贝数据到文本文件,或者直接从命令行打印文本文件。
在Unix中,这个点子是通过特殊目录下的特殊文件实现的,比如/dev/tty表示控制台,/dev/lp0表示第一个打印机等。/dev/zero可以提供无限的零,/dev/random可以提供随机字节,还有很多!
但有个问题:CP/M是为8位计算机设计的,这些计算机内存很小,也没有硬盘,最多也就有个8寸软驱。目录是什么?还要目录干啥。你换个软盘就行了。
但没有目录,就没办法把所有特殊文件都放在/dev/目录下了。所以这些文件实际上被放到了“所有地方”。所以,如果你要打印FOO.TXT,可以执行“PIP LST:=FOO.TXT”,就能把foo.txt拷贝到“文件”LST,而实际上这个就是打印机。
这个命令在任何地方都可以使用,因为根本没有目录!非常简单。
2、那扩展名怎么办?
这里就有问题了:程序喜欢给自己的文件加上正确的扩展名。
所以如果你运行一个程序,它问你“请输入要保存代码的文件名”时,你可以输入LST让它直接打印出来,或者输入PTP让它输出到磁带(别忘了现在是1974年!)
但是!程序可能会自己在文件名后面加上.TXT!LST.TXT不是打印机,对吧?
错了,LST.TXT也是打印机。这些特殊设备存在于所有扩展名中,这样上面的问题才不会出现。所以,如果“CON”被用来指代键盘,那么CON.TXT、CON.WAT、CON.BUG都是键盘。
额……这确实是个hack,但就是好使,而且这只不过是只有4k内存的微型计算机,谁在乎呢?
3、IBM、微软等巨头的加入
结果70年代末到80年代初CP/M广泛流行。
它是最主要的商用操作系统之一。它定义了一套接口,你可以用这套接口在NorthStar Horizon上写CP/M代码,然后放到Seequa Chameleon上运行(注:两者都是计算机的型号)。
由于它缺少图形标准,所以无法进入游戏市场(虽然有一些Infocom的东西),所以主要是用于商用。但它实在太流行了,于是IBM很自然地希望在80年代早期的“个人电脑”项目上使用它。
于是IBM计划在IBM个人电脑发布时支持几种操作系统,其中CP/M是最主要的那个。但CPM的x86版直到IBM个人电脑发布六个月之后才出现……而且价格是感人的$240,相比之下DOS只要$40。
所以绝大部分用户选择了微软的PC-DOS,这个产品曾经是由Seattle Computer Products开发的一个划时代的新操作系统。微软买下了Tim Paterson的这个项目,并在其基础上开发了PC-DOS(后来改名为MS-DOS)。
Tim Paterson的操作系统叫做“QDOS”,意思是“Quick and Dirty Operation System”——“快速、肮脏的操作系统”。原因基本上是因为CP/M还没有x86版,QDOS就是为了解决CP/M的一些问题而出现的。所以,很多方面都借鉴了CP/M。
其中主要的一点就是借鉴了不使用目录来操作特殊文件的点子,因为在CP/M中这个功能很有用。于是QDOS和PC-DOS 1.0中也有AUX、PRN、CON、LPT等等!
4、结果问题来了
1983年随着IBM XT一起发行的PC-DOS 2.0中的大部分被微软重写了。因为IBM XT带硬盘,所以PC-DOS需要支持目录。显然,一个10MB的硬盘需要目录来组织文件!
但问题来了:用户在两年前PC DOS 1.0时就开始使用这些特殊文件名了。许多软件都用了这些特殊文件名!各种批处理文件也需要它们。所以,尽管有了目录之后微软可以建一个C:DEV目录,但他们没有这样做。
这种牺牲可用性来满足向后兼容性的事情绝不是最后一次。特殊文件依然适用于所有目录,所有扩展名。所以“DIR > LPT”来打印目录的技巧不会由于你从A:切换到了C:DOS就不能用了。
但是,我们现在早就不用DOS 2.0了……Windows 95是基于DOS的,所以很自然地继承了这一行为。(当然Windows 1/2/3也继承了,但与它们相比,Win95才是真正意义上的操作系统。)
但是,我们现在早就不用Windows 95了!现在的Windows是基于Windows NT的,不是Win95。
但Windows NT想要与DOS/Windows程序兼容。而XP合并了两条产品线,所以这些特殊文件依然存在——这时距离这个bug出现已经过去44年了!
你可以自己试试看!打开文件管理器,新建一个文本文件,命名为con.txt、aux.txt、prn.txt。
但Windows不会让你这么干的:
这都是因为Gary Kiddal说“特殊文件表示硬件设备!Unix的这个点子很不错。我要把这个点子实现在我的玩具操作系统中”……那一年出生的人的孩子都长大成人了,但我们仍然不能建con.txt……
微软给出的官方列表是:
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9
https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
更有意思的是,在Win95上访问C:concon(或C:auxaux)会直接导致蓝屏。即使在1995年这也非常荒谬,因为这个bug已经21岁了!你能想象一个错误的设计会如此长寿么?
福利:下面这张图是Tim Paterson在今年8月的VCF:W上介绍DOS的历史。
至于为什么我发现了这个无法拷贝文件的bug……这些特殊文件名是在操作系统级别实现的,而不是文件系统级别。所以这些文件名完全是合法的NTFS文件名,而我在Linux下使用这些NTFS文件系统。
而且显然OS/2也没有实现这些特殊文件名,因为IBM在OS/2 devcon磁盘上发布的一些opengl头文件中有个文件叫AUX.H。
所以我今天想把这个NTFS盘备份到主PC上然后惊喜地发现,我没办法拷贝所有文件,而造成这个问题的bug的年龄比所有读者都大……
5、内容纠错
抱歉我这几天要么在医院里,要么在睡觉,好不容易才有机会上来更新一下:
1.CP/M对于特殊文件的处理方式其实不像我说的那么简单,所以我一直也没学会,也有可能学会了然后忘了。其实特殊文件后面要有个冒号,就跟盘符一样。比如PRN:是打印机,而PRN不是。
2.CP/M并不像DOS那样在操作系统层次实现!CP/M中是在PIP(文件复制)命令中实现的。所以没办法像DOS那样让程序直接保存到PRN.TXT进行打印。我可能没说清楚,我想说的是DOS,没有暗示CP/M也能这样做。
3.PC DOS 1其实没有重定向或管道,所以没办法像我说的那样做重定向。我忘记了。这些功能是1983年在PC DOS 2.0中加入的。但PC DOS 1的确支持从特殊文件中拷贝或拷贝到特殊文件,所以我说的大方向是对的,虽然例子搞错了。
不论如何,感谢大家的回复!我没想到这篇文章能这么火,其实它只是我在遇到一个44年的bug之后感到很无力而已。
而且我想重申,这篇文章并不是想说“Windows很垃圾”。一般来说,向后兼容是很好的。实际上我希望看到更多向后兼容。
我只是觉得,在Windows 10上从一个USB 3.0 SSD向另一个SSD拷贝文件时,遇到个44年前的bug很奇妙。
就像你在宇宙空间站中被马踢了一样。
6、开发者的看法
Hacker News上的很多开发者对于这个45岁的bug发表了自己的看法。
评论1:
好怀念那时的互联网……当时我们经常搜索21端口,就能找到很多开放了匿名FTP权限的机器,其中很多机器都是Windows的。
我们在这些匿名FTP上经常使用的“技巧”是:用这些特殊文件名创建一些嵌套的目录。在FTP服务器上,你可以创建这些目录,也可以访问它们(只要你知道正确的路径),但Windows下这些目录会导致错误,或者访问时会造成系统崩溃。再加上你可以创建文件名中只有空格的目录,所以可以在匿名FTP上放很多东西而不被管理员发现。
评论2:
我们高中的实验室中用的是Windows For Workgroups 3.11,我们用Alt+255(这个字符在DOS下像个空格,但在Windows下是隐藏的)来隐藏Doom、Descent还有很多其他DOS游戏的安装文件。
实验室管理员禁用了Ctrl+C和Ctrl+Break来防止有人退出DOS下的登录提示符直接进入C:,但我不知怎么发现了Alt+3也能输入同样的字符,起到同样的作用。
只有一次有个老师对我喊“在实验室里待了太长时间”,但我从来没被抓到过。我觉得管理员(上了点年纪的编程和数学老师)应该知道我们在干什么。
评论3:
好玩的是那些“COM”、“LTP”等后面加数字的……或者至少加上个像是数字的Unicode,所以COM²跟COM2一样不能用。
这种设备映射是在Win32层进行的,而不是NT内核上,所以你可以使用“verbatim path syntax”来越过这些规则。例如,“C:TempCOM2.TXT”是特殊设备,而“\?C:TEmpCOM2.TXT”就是个普通文件,完全可以正常读写……但像文件管理器这种没使用verbatim path syntax的程序就会报错。
精彩回顾
♡ 互联网公司各岗位真实工作内容起底
♡ 一次尴尬的采访和程序员的传奇脑洞!
♡ 天一冷,程序员都穿上格子衫
♡ 史上最真实的行业鄙视链曝光
♡ IT公司老板落水,各部门员工怎么救
♡ 宿命之战:程序员VS产品经理
♡ 作为一个前端,可以如何机智地弄坏一台电脑?
一个活了 45 年的「愚蠢」 Bug!相关推荐
- 微软“黑历史”:一个活了 45 年的愚蠢 Bug!
[CSDN编者按]微软于近期推出了Windows 10操作系统.不断压缩的更新周期下,一般而言,系统Bug的存活希望会被很快掐灭,快速迭代.但是本文的作者在Windows 10上从一个USB 3.0 ...
- 一个活了 45 年的愚蠢 Bug
不断压缩的更新周期下,一般而言,系统Bug的存活希望会被很快掐灭,快速迭代.但是本文的作者在Windows 10上从一个USB 3.0 SSD向另一个SSD拷贝文件时却遭遇了一个44年前的bug,他把 ...
- 一个活了 45 年的愚蠢 Bug!
译者:CSDN - 弯月 英文:https://threadreaderapp.com/thread/1058676834940776450.html 不断压缩的更新周期下,一般而言,系统Bug的存活 ...
- 从国企到互联网,一个六年程序员的「得」与「失」
程序员,六年,四段工作经历,这也许是一份会被很多 HR 刷掉的简历. 从学生时代至今,我经历了两次大的方向转型和一次大的技术转型:从偏理论推导的数学学科到重工程实践的计算机学科:从「安稳固化」的国企到 ...
- 一个 MVC 框架以 MVVM 之「魂」复活了!
Mokit 最初编写于 2012 年,是一个面向移动应用的前端 mvc 框架,v3 版本进行了大量的重构或重写,并尽可能的保持了和之前版本类似的 API, v3 是一个「极轻量」的 MVVM 框架,相 ...
- 如何把一个整数转化成数组_「leetcode891」给定一个整数数组 A,考虑 A 的所有非空子序列...
给定一个整数数组 A ,考虑 A 的所有非空子序列. 对于任意序列 S ,设 S 的宽度是 S 的最大元素和最小元素的差. 返回 A 的所有子序列的宽度之和. 由于答案可能非常大,请返回答案模 10^ ...
- 用专业的一个服装进销存软件「商陆花」做生意!太省事了
相信开过店的小伙伴们在进销存单.对账单.快递面单.仓库盘点这些一定很头疼吧!而且像之前刷卡的POS机,盘点库存的手持式盘点机一定不陌生,机器多了还容易弄错,机器的价格还贵.但是现在只要你有一部手机以上 ...
- 怎样对流媒体进行压力测试_对node工程进行压力测试与性能分析「干货」
作者:小黎 转发链接:https://mp.weixin.qq.com/s/WBe7ZLoqFD9UqNusnv_IDA 前言 在系统上线前,为了看下系统能承受多大的并发和并发下的负载情况,常常会先进 ...
- 无需「域外」文本,微软:NLP就应该针对性预训练
在生物医学这样的专业领域训练NLP模型,除了特定数据集,「域外」文本也被认为是有用的.但最近,微软的研究人员「大呼」:我不这么觉得! 什么是预训练? 这是一个拷问人工智能「门外汉」的灵魂问题. 生而为 ...
最新文章
- Android多线程死锁定位,Java---多线程之死锁
- inode客户端连接成功上不了网_wifi连接上但上不了网怎么回事
- 用户生命周期管理,整体运营的基础与核心
- Smzzl with Greedy Snake 模拟-贪心-阅读理解
- PHP PDO 预处理语句与存储过程
- EZNEW.NET开发框架100%重磅开源
- log4net部分配置说明
- OpenStack不行了吗?悉尼峰会,OpenStack的白城反击战?
- 移动端touch与click
- 2016二级c语言成绩查询,2016年12月计算机二级C语言测试及答案
- MySQL日志(一条sql更新语句是如何执行的)
- 5.1 凸二次规划问题
- 计算机flash教案,flash教学计划
- 3DMAX下载、3dmax2014下载、3dmax2020下载亲测有效
- 关于黑莓手机 三键重启的操作方法
- kettle 使用excel模板导出数据
- 苦刷面试题七天七夜,四面蚂蚁,百度双双通过,最终选择了腾讯!
- Java 文件与字节流操作
- 输入一个包含若干数据的列表,先将列表中的数由小到大进行排序,然后将值为负数的元素进行平方运算
- 使用Keras编写神经网络预测大乐透彩票,并利用历史数据回测