Linux 的 touch 命令用来修改文件时间戳,或者新建一个不存在的文件,使用方式如下:

touch [-acm][-r ref_file(参照文件)|-t time(时间值)] file(文件名)

本实验基于C语言实现Linux touch命令的 [-acm]选项。

注:

touch file1.txt 更新 file1.txt 的存取和修改时间

touch -a file1.txt 改变 file1.txt 的读取时间记录

touch -c file1.txt 如果 file1.txt 不存在,不创建文件

touch -m file1.txt 改变 file1.txt 的修改时间记录

touch命令就是修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。

getopt函数:解决参数处理的函数。

//头文件
#include<unistd.h>
//函数原型:
int getopt(int argc,char * const argv[ ],const char * optstring);

函数介绍:分析命令参数。

返回值:参数字符。

open函数:

函数 open 是 UNIX 系统的系统调用函数,区别于 C 语言库函数 fopen。

//头文件:
#include<fcntl.h>
//函数原型
int open(constchar*pathname, int flags);
int open(constchar*pathname, int flags, mode_t mode);

函数作用:打开和创建文件。

返回值:成功返回文件描述符,失败返回-1。

参数说明:

对于 open 函数来说,第三个参数仅当创建新文件时(即使用了 O_CREAT 时)才使用,用于指定文件的访问权限位(access permission bits)。pathname 是待打开/创建文件的 POSIX 路径(如/home/user/a.cpp);flags 用于指定文件的打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑位或逻辑构成。

O_RDONLY 只读模式

O_WRONLY 只写模式

O_RDWR 读写模式

参数 mode 则有下列数种组合, 只有在建立新文件时才会生效, 此外真正建文件时的权限会受到 umask 值所影响, 因此该文件权限应该为 (mode-umaks).

S_IRWXU 00700 权限, 代表该文件所有者具有可读、可写及可执行的权限.

S_IRUSR 或S_IREAD, 00400 权限, 代表该文件所有者具有可读取的权限.

S_IWUSR 或S_IWRITE, 00200 权限, 代表该文件所有者具有可写入的权限.

S_IXUSR 或S_IEXEC, 00100 权限, 代表该文件所有者具有可执行的权限.

S_IRWXG 00070 权限, 代表该文件用户组具有可读、可写及可执行的权限.

S_IRGRP 00040 权限, 代表该文件用户组具有可读的权限.

S_IWGRP 00020 权限, 代表该文件用户组具有可写入的权限.

S_IXGRP 00010 权限, 代表该文件用户组具有可执行的权限.

S_IRWXO 00007 权限, 代表其他用户具有可读、可写及可执行的权限.

S_IROTH 00004 权限, 代表其他用户具有可读的权限

S_IWOTH 00002 权限, 代表其他用户具有可写入的权限.

S_IXOTH 00001 权限, 代表其他用户具有可执行的权限.

函数utimensat

//头文件
#include<sys/stat.h>
//函数原型
int utimensat(int dirfd, const char *pathname,const struct timespec times[], intflags);

作用:utimensat 是以纳秒级的精度改变文件的时间戳。utimensat()通过文件的路径(pathname)获得文件。

这个系统调用函数都是通过一个时间数组 times 来改变时间戳的,times[0] 修改最后一次访问的时间(access time),times[1] 修改最后修改的时间 (modify time)。该时间数组是由秒和纳秒两个部分组成,数据结构如下:

特别注意:

当 times[x].tv_sec = UTIME_OMIT; 相应的时间戳不变,times[x].tv_sec = UTIME_NOW; 相应的时间戳编程当前时间。

实例:

#include<stdio.h>
#include<getopt.h>
#include<sys/types.h>
#include<time.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdbool.h>
#include<sys/time.h>
#include<sys/stat.h> #define CH_ATIME 1
#define CH_MTIME 2 //定义创建文件时的模式,此处对用户,组,其他设置的权限都是可读可写。
#define MODE_RW_UGO (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |S_IWOTH) //标志文件access time 和 modify time的改变情况
static int change_times; // 如果有(-c)选项,并且不存在命令行中输入的文件名,则不创建
static bool no_create; //当设置新的access time 和 modify time的时候使用
static struct timespec newtime[]; //mytouch命令核心的核心模块,用于创建或者更新文件的时间戳。
static bool mytouch(const char *file)
{
bool ok;
int fd = -;
if (!no_create)
{
fd = open(file, O_CREAT | O_WRONLY, MODE_RW_UGO);
} //在主函数中,如果没有检测到(-a)(-m),则change_times == (CH_ATIME | CH_MTIME),\
否则按照选项只用改变其中一个时间戳。
if (change_times !=(CH_ATIME | CH_MTIME))
{
//只设定其中一个时间值。 /*如果change_times == CH_MTIME,即(-m),将对应的修改access time
的timespec结构的tv_nsec设置为UTIME_OMIT;参考utimensat函数的用法*/
if (change_times == CH_MTIME)
{
newtime[].tv_nsec = UTIME_OMIT;
} /*如果change_times == CH_MTIME,即(-a),将对应的修改modify time
的timespec结构的tv_nsec设置为UTIME_OMIT;参考utimensat函数的用法*/
else
{
//AT_FDCWD表示当前工作目录。
newtime[].tv_nsec = UTIME_OMIT;
}
}
ok = (utimensat(AT_FDCWD, file, newtime, ) == );
return true;
} int main(int argc, char **argv)
{
int c;
bool ok = true;
change_times = ;
no_create = false; //从命令行中得到命令的选项,即以'-'开头的参数。目前只支持三种选型-a, -c, -m。
while ((c = getopt(argc, argv, "acm")) != -)
{
switch(c)
{
case 'a':
change_times |= CH_ATIME;
break;
case 'c':
no_create = true;
break;
case 'm':
change_times |= CH_MTIME;
break;
default:
printf("fault option!");
}
} if (change_times == )
{
change_times =CH_ATIME | CH_MTIME;
} newtime[].tv_nsec = UTIME_NOW;
newtime[].tv_nsec = UTIME_NOW; //如果optind == argc,代表少输入文件名字
if (optind == argc)
{
printf("missing file operand\n");
} //针对多个文件名字调用mytouch函数
for (; optind < argc; ++optind)
{
ok &= mytouch(argv[optind]);
}
exit(ok ? EXIT_SUCCESS : EXIT_FAILURE);
}

运行结果:

touch 创建文件

touch -a 命令

touch -m

touch -c

C实现Linux之touch命令的更多相关文章

  1. linux中touch命令参数修改文件的时间戳(转)

    linux中touch命令参数不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存在的文件,以下是linux中touch命令参数的使用方法: touch [-acm][-r ...

  2. linux中touch命令参数修改文件的时间戳(转载)

    转自:http://os.51cto.com/art/200908/144237.htm linux中touch命令参数不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存 ...

  3. linux的touch命令

    linux的touch命令不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存在的文件. 1.命令格式: touch [选项]... 文件... 2.命令参数: -a    ...

  4. 【Linux】touch命令

    用途 touch命令参数可更改文档或目录的日期时间,包括存取时间和更改时间. 全称 touch全称即为touch 参数 -a   :或--time=atime或--time=access或--time ...

  5. Linux中touch命令使用(创建文件)

    touch命令有两个功能: 1.用于把已存在文件的时间标签更新为系统当前的时间(默认方式),它们的数据将原封不动地保留下来: 2.用来创建新的空文件. 语法 touch(选项)(参数) 选项 -a:或 ...

  6. linux之touch命令修改文件的时间戳

    功能:对已经存在文件的时间进行修改,存取时间(access time).修改时间(modification time).对不存在的文件,进行创建新的空白文件. 语法:touch   [选项]  文件 ...

  7. 每天一个linux命令(9):touch 命令

    linux的touch命令不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存在的文件. 1.命令格式: touch [选项]... 文件... 2.命令参数: -a    ...

  8. 每天一个Linux命令(09)--touch命令

    linux的touch命令不常用,一般在使用make的时候可能会用到,用来修改文件时间戳,或者新建一个不存在的文件. 1.命令格式: touch  [选项]··· 文件··· 2.命令参数: -a 或 ...

  9. linux每日命令(10):touch命令

    linux的touch命令一般用来修改文件时间戳,或者新建一个不存在的文件. 一.命令格式: touch [参数]... 文件... 二.命令参数: 参数 描述 -a 或--time=atime或-- ...

随机推荐

  1. 使用spring jpa hibernate框架时报错:javax.validation.UnexpectedTypeException: HV000030

    错误信息: [#%&*^]20190521121942:497.!react:all.,RctJobExecutor-1#D9AA5167921A464CA9DDA14943545426%NA ...

  2. zipkin微服务调用链分析(python)

    一,概述 zipkin的作用 在微服务架构下,一个http请求从发出到响应,中间可能经过了N多服务的调用,或者N多逻辑操作,如何监控某个服务,或者某个逻辑操作的执行情况,对分析耗时操作,性能瓶颈具有很 ...

  3. 在ASP.NET Core中添加的Cookie如果含有特殊字符,会被自动转义

    我们知道在Cookie中有些字符是特殊字符,这些字符是不能出现在Cookie的键值中的. 比如"="是Cookie中用来分隔键和值的特殊字符,例如:Key01=Value01,表示 ...

  4. iTextSharp生成pdf含模板(一)---制作pdf模板

    参考地址:https://www.cnblogs.com/ibeisha/p/itextsharp-pdf.html 一.使用场景:在线填写一些信息,根据对应的信息生成奖状. 二.解决方案 1.新建w ...

  5. poj3045 Cow Acrobats (思维,贪心)

    题目: poj3045 Cow Acrobats 解析: 贪心题,类似于国王游戏 考虑两个相邻的牛\(i\),\(j\) 设他们上面的牛的重量一共为\(sum\) 把\(i\)放在上面,危险值分别为\ ...

  6. 何为KVM克隆和快照

    KVM的克隆.快照都是老生常谈的问题,资料也非常多,这里只是针对个人实验的记录,方便以后查阅. 虚拟机克隆 虚拟机的克隆操作是再频繁不过了,安装好第一台虚拟机后就可以进行基础设置,已此虚拟机为模板,以 ...

  7. JS基石之-----数组转换为树结构函数

    我们常常在做后台管理系统的时候 需要对数据进行组装成一个树装结构,这里特地将此方法进行封装: let data = [ { id: , text: }, { id: , text: }, { id: ...

  8. 被严重误会?APS系统没有想象的那么复杂

    APS的出现要从90年代了,但到现在,很多行业内的顾问或用户提到APS都马上想到的是“要求很精确”“难度很大”“脱离实际”“太理想化”“工作量太大”等等,然后把它束之高阁不睬. 在这里,给大家分析一下 ...

  9. android studio学习----构建(gradle )依赖时使用动态依赖的问题

    今天在看Dan Lew大神的博客发现最新的文章就是 “Don't use dynamic versions for your dependencies” Everyone, please, to st ...

  10. Shell 编程 文本处理工具 sed

    本篇主要写一些shell脚本文本处理工具sed的使用. 概述 sed(Stream EDitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除.替换.添加 ...