【问题标题】:How to check if soft link exists or not如何检查软链接是否存在
【发布时间】:2021-03-24 02:10:59
【问题描述】:
user: ls -lt
lrwxrwxrwx 1 user sw-team    9 Jun 18 19:01 new_link -> test/file

我有一个如上所述的软链接。我想检查 new_link(不是链接文件)是否存在。我尝试了以下所有方法,但都只检查最终目标文件(测试/文件)是否存在。

access(filename,F_OK)
stat()
open()
fopen()

我想用 C 语言而不是 shell 脚本找到它。请告诉我在检查链接文件之前如何查找 new_link 是否存在?

【问题讨论】:

  • 如果符号链接不存在,你尝试的所有机制都会报错。但是,如果符号链接存在,但它指向的路径的某些部分会导致问题(不存在或您没有权限或在需要时不是目录),他们也会报告错误。

标签: c linux symlink


【解决方案1】:

使用lstat - 获取符号链接状态:

lstat() 函数应等效于stat(),除非路径指的是符号链接。在这种情况下,lstat() 应返回有关链接的信息,而stat() 应返回有关链接引用的文件的信息。

(强调我的。)

lstat 将返回非零值,如果链接(或路径的任何其他部分)不存在,errno 将设置为 ENOENT

例子:

#include <stdio.h>
#include <stdbool.h>
#include <sys/stat.h>

bool symlink_exists(const char* path)
{
    struct stat buf;
    int result;

    result = lstat(path, &buf);

    return (result == 0);
}

void test(const char* path)
{
    bool exists = symlink_exists(path);

    printf("%s does%s exist.\n", path, exists ? "" : " not");
}

int main(int argc, char** argv)
{
    test("/bin/sh");
    test("/etc/no_such_thing");
    return 0;
}

输出:

/bin/sh does exist.
/etc/no_such_thing does not exist.

【讨论】:

  • 谢谢。但如果我删除目标文件,它就不起作用
  • @Jonathon 函数symlink_exists 在它的当前实现中只回答路径是否存在,而不是路径是符号链接还是常规文件。当使用lstat 时,如果 路径是符号链接,缓冲区将保存关于它的数据,而不是关于指向的数据,而不仅仅是stat。但是您仍然需要检查文件类型(将出现在提供的struct stat 缓冲区的st_mode 字段中)。请参阅man page 中的示例
【解决方案2】:

您需要lstat 来获取链接状态和readlink 来读取符号链接的值。 我修改了 Jonthon 的代码。检查这个:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <sys/stat.h>

bool symlink_exists(const char* path)
{
    struct stat buf;
    int ret = 0;
    char *linkname;


    if (lstat(path, &buf) == 0) {
       // TODO: Add error handling
       linkname = malloc(buf.st_size + 1);
       readlink(path, linkname, buf.st_size + 1);
       linkname[buf.st_size] = '\0';
       printf("---> '%s' points to '%s'\n", path, linkname);
       if (stat(linkname, &buf) == 0)
           ret = 1;
    }
    return ret;
}

void test(const char* path)
{
    bool exists = symlink_exists(path);

    printf("%s does%s exist.\n", path, exists ? "" : " *not*");
}

int main(int argc, char** argv)
{
   test("/bin/sh");            //Normal link using relative path - NOT WORKING
   test("/etc/no_such_thing"); //Broken file
   test("tmpp");               //Normal link using absolute path - WORKING 
   test("tmppp");              //Broken link  
   return 0; 
}

使用绝对路径创建链接。否则,您必须将其转换为相对路径。

【讨论】:

【解决方案3】:

简答:

#include <sys/stat.h>
#include <string>

bool symlinkExists(const string &path)
{
    struct stat info;
    return lstat(path.c_str(), &info) == 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 2012-11-30
    相关资源
    最近更新 更多