Linux unlink / unlinkat / remove 函数

本文详细介绍了Linux系统中unlink、unlinkat和remove这三个函数的功能和使用示例。unlink只能删除文件,而unlinkat通过AT_REMOVEDIR标志可以删除文件或目录。remove函数则可以删除文件或目录,类似于unlinkat但无需指定类型。通过实例展示了它们在删除文件和目录时的行为差异。此外,还讨论了如何通过open和unlink创建临时文件的原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、函数声明

#include <unistd.h>
int unlink(const char *pathname);


#include <fcntl.h>           /* Definition of AT_* constants */
#include <unistd.h>
int unlinkat(int dirfd, const char *pathname, int flags);


#include <stdio.h>
int remove(const char *pathname);
  • unlink 只可以删除文件。
  • unlinkat 可以删除文件(默认)或文件夹(需要设置 flags 为 AT_REMOVEDIR)。
  • remove 可以删除文件,或者文件夹。【可以认为 remove 底层是 unlinkat 一样的实现,只不过不需要针对是文件夹时,指定参数 AT_REMOVEDIR】 

二、实例

2.1、基本使用(删除文件,与目录)

2.1.1、unlink (结果,文件删除成功,无法删除目录)

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **args)
{
    if (unlink("test") < 0) {
        perror("unlink file test with fail");
        exit(-1);
    }

    return 0;
}

hotice0@ubuntu:~/Documents/Unix_Program$ touch test
hotice0@ubuntu:~/Documents/Unix_Program$ ./main
hotice0@ubuntu:~/Documents/Unix_Program$ mkdir test
hotice0@ubuntu:~/Documents/Unix_Program$ ./main 
unlink file test with fail: Is a directory
 

2.1.2、跟踪 rm -r (其使用的是 unlinkat 系统调用) 

跟踪命令 strace rm -r test,结果如下

...
unlinkat(AT_FDCWD, "test", AT_REMOVEDIR) = 0
...

2.1.3、unlinkat (带 AT_REMOVEDIR 时,能删除文件夹,不带时能删除文件) 

#define __USE_ATFILE

#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>


int main(int argc, char **args)
{
    if (unlinkat(AT_FDCWD, "test", AT_REMOVEDIR) < 0) {
        perror("unlinkat file test with fail");
        exit(-1);
    }
    return 0;
}

hotice0@ubuntu:~/Documents/Unix_Program$ mkdir test
hotice0@ubuntu:~/Documents/Unix_Program$ ./main 
hotice0@ubuntu:~/Documents/Unix_Program$ touch test
hotice0@ubuntu:~/Documents/Unix_Program$ ./main 
unlinkat file test with fail: Not a directory 

2.1.4、remove(可以删除文件,或者文件夹)

// 简单的实例
#include <stdio.h>

int main(int argc, char **args)
{
    remove("test");
    return 0;
}

 2.2、创建临时文件

即,首先通过 open 打开并创建文件,随后调用 unlink 减少文件计数。但是由于该文件被程序打开,所以文件不会被立即删除,而是进程退出时,内核会判断没有其他进程打开该文件,并且文件链接数为 0,才会真正的删除文件。

下面是用于验证的程序

#define __USE_ATFILE

#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF_SIZE 1024

int main(int argc, char **args)
{
    int fd;
    char buf[BUF_SIZE] = {0};
    
    fd = open("test", O_CREAT|O_RDWR, S_IRWXU);
    if (fd < 0) {
        perror("open with fail");
        exit(-1);
    }
    printf("file created\n");
    sleep(5);
    if (unlink("test") < 0) {
        perror("unlink file test with fail");
        close(fd);
        exit(-1);
    }

    printf("unlinked\n");
    sleep(5);

    if (write(fd, "hotice0", strlen("hotice0")) < 0) {
        perror("write with fail");
        close(fd);
        exit(-1);
    }

    if (lseek(fd, 0, SEEK_SET) < 0) {
        perror("lseek with fail");
        close(fd);
        exit(-1);
    }

    if (read(fd, buf, BUF_SIZE) < 0) {
        perror("read with fail");
        close(fd);
        exit(-1);
    }

    printf("read from file test: %s\n", buf);

    close(fd);
    printf("closed file\n");

    return 0;
}

这个程序很简答,首先创建 test 文件,然后 sleep 5s,再调用 unlink 删除该文件,再 sleep 5s,再向文件写入,内容并且读出,然后 close 文件。 

// A terminal
./main
file created
unlinked
read from file test: hotice0
closed file

// B terminal
hotice0@ubuntu:~/Documents/Unix_Program$ ll test    // 这一步是在open test文件之后,文件就存在了
-rwx------ 1 hotice0 hotice0 0 Aug  8 00:34 test*
hotice0@ubuntu:~/Documents/Unix_Program$ ll test     // 这一步是在unlink调用之后,文件在该目录中无法找到了
ls: cannot access 'test': No such file or directory

三、总结

  1. unlink 默认,只能删除文件的链接。
  2. unlinkat可以通过flag参数,是否是 AT_REMOVEDIR,控制删除文件还是文件夹。
    (所以可以通过 open 打开文件后,通过 stat 获取文件类型,根据类型决定是否使用AT_REMOVEDIR)。
  3. remove 函数作用其实和 unlink 和 unlinkat 作用是一样的,但是可以删除文件和文件夹,不需要指定类型(是文件还是文件夹)。

转载:Linux unlink/unlinkat/remove 函数_HotIce0的博客-CSDN博客_unlinkat

(SAW:Game Over!)


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值