”新建文件”只是早期Unix上touch命令的副作用?程序别挂掉就行

在西斯廷教堂的天顶上,米开朗基罗留下了人类艺术史上最具张力的名作——《创造亚当》。画面中,上帝在天使的簇拥中俯身而下,手指即将触碰到大地之上的亚当。这一指尖交会的瞬间,凝结了“以神之手创造人类”的想象,也象征着生命、自由意志、甚至灵魂的诞生

看到这幅画的时候,我脑中突然冒出一个念头:*nix系统里的touch命令,会不会也是受此启发?在操作系统的世界里,用户就是数字造物主,只需手指一点,“touch”一下,文件便无中生有,颇有几分神性。

直到有一天,在翻阅了早期Unix系统上touch命令的源码之后,才发现这个命令最初的设计目的,其实只是单纯地修改文件的最后修改时间。至于“新建文件”,那只不过是一个顺带发生的副作用,甚至可以说是一种不得已而为之的行为。

今天,我们就来聊聊早期Unix系统中touch命令的实现方式,看看这个朴素的命令是如何在阴差阳错中,被误解为“神之触碰”的。

Unix V7中的touch.c

touch命令的最初版本可以追溯到1979年发布的Unix第7版。那时,它还只是一个不到100行的小程序。在当年的手册页里,touch命令被简洁地描述为:“update date last modified of a file”——即修改文件的最后变更时间

有趣的是,源码touch.c里采用了一种颇为“狡猾”的技巧:通过假装修改文件内容,来“欺骗”系统更新时间戳。具体做法如这几行代码所示:

char junk[1];
int fd;

...

if( read(fd, junk, 1) < 1)
    {
    close(fd);
    goto bad;
    }
lseek(fd, 0L, 0);
if( write(fd, junk, 1) < 1 )
    {
    close(fd);
    goto bad;
    }
close(fd);

bad:
    fprintf(stderr, "Cannot touch %s\n", name);
    return;

这里先读取了1个字节,然后立刻原样写回这个字节。相当于,选中——Ctrl+C——保持选中Ctrl+V。这样一来,在文件内容不变的前提下,就间接地更新了文件的最后修改时间

乍一看,这种“伪修改”的方法相当机智,但也有个明显的问题:要想成功读取并写回1个字节,文件首先必须存在,其次还得至少有1个字节的内容。换句话说,空文件根本不存在的文件就像现代编程语言中的null——必须特殊对待,一旦处理不当,就会导致程序出错甚至崩溃。

touch的作者显然也意识到了尴尬的“null“。于是,他们加了一个简单粗暴的补丁:文件不存在?那就新建一个呗。文件是空的?那就再重新创建一遍呗。问题迎刃而解!

就这样,原本只想“更新时间”的命令,顺带就拥有了新建文件的能力。这完全是出于工程上的权宜之计——既非神启,也非致敬米开朗基罗。创造这个动作,在这里只是为了让程序别挂掉而已。

至于新建文件的实现方式,就藏在touch.c最后的几行代码中,而那几行,也有一个小小的故事。

拼写错误的creat

新建文件的代码如下所示:

create:
    if( (fd = creat(name, 0666)) < 0)
        goto bad;
    close(fd);

从这几行源代码可以看出,touch是通过调用一个名为creat的函数(系统调用)来新建文件的。引人注目的是,这个creat少了末尾的字母“e”,而在上方作为标签的create:却是拼写正确的。

是贝尔实验室的理工男文科太差,连单词都拼写错了?还是这是一种程序员式的极简主义——为了少敲一个键,干脆把单词缩写了?又或者,是受限于当年计算资源的紧张,不得不节省每一个字符?

总之,为什么把“create”写成“creat”,这个问题多年来始终为程序员们津津乐道。各种猜测和玩笑层出不穷,直到有一次,Unix的共同缔造者之一Ken Thompson在采访中被问到,“如果你能重新设计UNIX,会改些什么?”。

”新建文件”只是早期Unix上touch命令的副作用?程序别挂掉就行_第1张图片

Ken幽默地回答说:“我会把creat拼成带e的create”。


说起来,用touch作为修改文件时间的命令,其实还挺贴切的。毕竟,如果你没“碰”这个文件,当然“毫无变化”,自然也不该更新它的时间戳;但如果碰了,那就像留下了“最新的指纹”一样,时间戳也就随之更新。

顺带一提,把touch理解成“触碰”既能表达轻微的变更,又点出了后果——文件状态发生变化。但如果理解成“摸一把”来创建文件、更新时间,那就不太妙了……因为「痴漢は犯罪!」。

”新建文件”只是早期Unix上touch命令的副作用?程序别挂掉就行_第2张图片

你可能感兴趣的:(unixlinux命令行历史)