当前位置 博文首页 > lyndon:touch,一个被大多数程序员误解的命令,你中招了吗?

    lyndon:touch,一个被大多数程序员误解的命令,你中招了吗?

    作者:[db:作者] 时间:2021-08-23 16:20

    误解

    如果,你问一个程序员,touch 命令是干什么的?

    我相信 10 个里面有 8 个会回答:创建一个空文件。

    然而,事实真的如此吗?

    本意

    man touch
    在这里插入图片描述

    Linux man 手册里面介绍 到 touch - change file timestamps。所以,touch 的本意是改变文件的时间戳,即,将文件的访问时间和修改时间改为当前时间。

    澄清

    所以,创建一个空文件,只是 touch 的功能只一:当文件不存在时,使用当前时间创建一个空文件。

    甚至,创建空文件你仍然可以理解为是改变文件的时间戳,改变为现在,也就从无到有创建了。另一种理解,一个文件不可能只有访问时间和修改时间而没有创建时间(那太邪乎了),而 touch 为了完成修改文件的访问时间和修改时间的使命,不得已要给文件一个创建时间,就这样(误打误撞)把一个文件给创建了。

    以上内容纯属瞎扯,哈哈!😜

    一句话,『Talk is cheap. Show me the code』 👇

    源码

    /* Update the time of file FILE according to the options given.
       Return 0 if successful, 1 if an error occurs. */
    static int touch(const char *file)
    {
    ...
        /* 文件不存在先创建 */
    	if (!no_create) {
    		/* Try to open FILE, creating it if necessary.  */
    		fd = open(file, O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY,
    				  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    
    		/* Don't save a copy of errno if it's EISDIR, since that would lead
    		 touch to give a bogus diagnostic for e.g., `touch /' (assuming
    		 we don't own / or have write access to it).  On Solaris 5.6,
    		 and probably other systems, it is EINVAL.  On SunOS4, it's EPERM.  */
    		if (fd == -1 && errno != EISDIR && errno != EINVAL && errno != EPERM)
    			open_errno = errno;
    	}
    ...
        /* 更新文件的访问时间和修改时间 */
    	if (amtime_now) {
    		/* Pass NULL to utime so it will not fail if we just have
    		 write access to the file, but don't own it.  */
    		status = utime(file, NULL);
    	} else {
    		struct utimbuf utb;
    
    		/* There's currently no interface to set file timestamps with
    		 better than 1-second resolution, so discard any fractional
    		 part of the source timestamp.  */
    
    		if (use_ref) {
    			utb.actime = ref_stats.st_atime;
    			utb.modtime = ref_stats.st_mtime;
    		} else
    			utb.actime = utb.modtime = newtime;
    
    		if (!(change_times & CH_ATIME))
    			utb.actime = sbuf.st_atime;
    
    		if (!(change_times & CH_MTIME))
    			utb.modtime = sbuf.st_mtime;
    
    		status = utime(file, &utb);
    	}
    ...
    	return 0;
    }
    

    从源码中可以清楚看到,touch 先检查文件是否存在,不存在就先创建,然后使用 utime() 系统调用,修改文件的访问时间和修改时间。

    cs
    下一篇:没有了