【问题标题】:How to get absolute path of a symbolic link?如何获取符号链接的绝对路径?
【发布时间】:2016-07-20 06:15:30
【问题描述】:

如何获取符号链接的绝对路径?如果我按以下方式进行:

char buf[100];
realpath(symlink, buf);

我不会得到符号链接的绝对路径,而是会得到这个符号链接链接到的绝对路径。现在我的问题是:如果我想获得符号链接本身的 abs 路径怎么办? Linux c 中是否有任何功能可以让我这样做? 注意:我想要实现的是符号链接本身的绝对路径。不是它指向的路径!例如一个符号链接的相对路径是:Task2/sym_lnk,我想要它的绝对路径,可以是:home/user/kp/Task2/sym_lnk

【问题讨论】:

  • 这是特定于操作系统的。 (标准库没有符号链接的概念。) Linux?然后将其标记为这样。
  • 试试stackoverflow.com/questions/16017500/…。 IT 建议尝试readlink
  • @shapiroyaacov 虽然该问题针对的是命令行,但它可能指向正确的方向,因为存在同名的 glibc 函数。

标签: c


【解决方案1】:

您可以将 realpath() 函数与符号链接的父文件夹一起使用,然后连接符号链接名称。

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

// Find the last occurrence of c in str, otherwise returns NULL
char* find_last_of( char *str, char c )
{
    for( char *i = str + strlen(str) ; i >= str ; i-- )
        if( *i == c )
            return i;
    return NULL;
}

// Does the job
char* getAbsPath( char *path  )
{
    char *name; // Stores the symlink name
    char *tmp; // Aux for store the last /
    char *absPath = malloc( PATH_MAX ); // Stores the absolute path

    tmp = find_last_of( path, '/' );

    // If path is only the symlink name (there's no /), then the
    // parent folder is the current work directory
    if( tmp == NULL ){ 
        name = strdup( path );
        getcwd( absPath, PATH_MAX ); // Is already absolute path
    }
    else{
        // Extract the name and erase it from the original
        // path.
        name = strdup( tmp + 1 );
        *tmp = '\0';
        // Get the real path of the parent folder.
        realpath( path, absPath );
    }
    // Concatenate the realpath of the parent and  "/name"
    strcat( absPath, "/" );
    strcat( absPath, name );
    free( name );
    return absPath;
}

// Test the function
int main( int argc, char **argv )
{
    char *absPath;

    if( argc != 2 ){
        fprintf( stderr, "Use:\n\n %s <symlink>\n", *argv );
        return -1;
    }
    // Verify if path exists
    if( access( argv[1], F_OK ) ){
        perror( argv[1] );
        return -1;
    }

    absPath = getAbsPath( argv[1] );
    printf( "Absolute Path: %s\n", absPath );
    free( absPath );
    return 0;
}

如果您将上述代码与目录一起使用,则“。”需要特殊情况。和“..”,但适用于“./”和“../”

【讨论】:

    【解决方案2】:

    可以使用系统调用readlink()

    readlink(const char* fdpath,char* filepath, 256);
    

    fdpath 是符号链接的path。类似/proc/pid/fd/link_number

    filepath是它指向的文件的路径

    【讨论】:

    • 如何确定最后一个 argm '256'?如何事先知道文件路径的长度?
    • @Kindermann,在我的项目中,我所做的是采用足够大的字符串来适应任何路径。除非它有些可笑的长[路径,我认为你会用 256 或 512 做得很好
    • @Kindermann:“我如何确定最后一个 argm '256'?”参见limits.h中的PATH_MAX常量
    • @Haris,你能看看我上面的注释。我想获取符号链接本身的 abs 路径,但 filepath 是它指向的文件的路径......它们是否相同?
    • @Kindermann:或者,使用动态分配的缓冲区,并在循环中调用readlink;只要readlink 一直返回与bufsiz 相同的值,您就可以realloc 缓冲区(一次增加倍数或某个固定字节数)并重试。当返回值与bufsiz 不匹配时,手动将NUL 插入到返回值的索引处(因为readlink 不适合你),你就完成了。要进行测试,请从一个小的 bufsiz 开始,以便验证您是否正确展开。
    猜你喜欢
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多