目录递归和符号链接 [英] Directory recursion and symlinks

查看:182
本文介绍了目录递归和符号链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您通过明显的方法递归地浏览目录树,则当符号链接指向父目录时,您将无限次递归遇到麻烦。



解决方案将是检查符号链接,而不是按照它们。但是,对于不希望为其他目的而言,如完全正常的目录的行为被默默忽略的用户,这可能是一个令人不快的惊喜。



另一种解决方案可能是保持目前访问的所有目录的哈希表,并使用它来检查循环。但是,这将需要有一些规范的表示(某种方式来获取您目前正在查看的目录的身份)(无论您到达目标路径)。



如果是这样,有没有办法获得这样一个目录的规范表示/身份,那就是可跨Unix系统移植? (我希望它可以在Linux,BSD,Mac OS,Solaris等上工作。我希望为Windows编写单独的代码。)

解决方案

此字段中最常被忽略的API将是



nftw



Nftw有选项来避免它遍历符号链接。它具有比这更高级的功能。以下是手册页本身的简单示例:

  #define _XOPEN_SOURCE 500 
#include< ftw.h> ;
#include< stdio.h>
#include< stdlib.h>
#include< string.h>
#include< stdint.h>

static int
display_info(const char * fpath,const struct stat * sb,
int tflag,struct FTW * ftwbuf)
{
printf %-3s%2d%7jd%-40s%d%s\\\

(tflag == FTW_D)?d:(tflag == FTW_DNR)?dnr:
(tflag == FTW_DP)?dp:(tflag == FTW_F)?f:
(tflag == FTW_NS)?ns:(tflag == FTW_SL)?sl:
(tflag == FTW_SLN)?sln:???,
ftwbuf-> level,(intmax_t)sb-> st_size,
fpath,ftwbuf-> base, fpath + ftwbuf-> base);
return 0; / *告诉nftw()继续* /
}

int
main(int argc,char * argv [])
{
int flags = 0;

if(argc> 2&& strchr(argv [2],'d')!= NULL)
flags | = FTW_DEPTH;
if(argc> 2&& strchr(argv [2],'p')!= NULL)
flags | = FTW_PHYS;

if(nftw((argc< 2)?。:argv [1],display_info,20,flags)
== -1)
{
perror(nftw);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}

另请参阅




If you recursively traverse a directory tree by the obvious method, you'll run into trouble with infinite recursion when a symlink points to a parent directory.

An obvious solution would be to just check for symlinks and not follow them at all. But that might be an unpleasant surprise for a user who doesn't expect what behaves for other purposes like a perfectly normal directory to be silently ignored.

An alternative solution might be to keep a hash table of all directories visited so far, and use this to check for loops. But this would require there to be some canonical representation, some way to get the identity, of the directory you are currently looking at (regardless of the path by which you reached it).

Would Unix users typically regard the second solution as less surprising?

If so, is there a way to obtain such a canonical representation/identity of a directory, that's portable across Unix systems? (I'd like it to work across Linux, BSD, Mac OS, Solaris etc. I expect to have to write separate code for Windows.)

解决方案

The most frequently ignored API in this field would be

nftw

Nftw has options to avoid it traversing symlinks. It has much more advanced capabilities than that. Here is a simple sample from the man page itself:

#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

static int
display_info(const char *fpath, const struct stat *sb,
             int tflag, struct FTW *ftwbuf)
{
    printf("%-3s %2d %7jd   %-40s %d %s\n",
           (tflag == FTW_D) ?   "d"   : (tflag == FTW_DNR) ? "dnr" :
           (tflag == FTW_DP) ?  "dp"  : (tflag == FTW_F) ?   "f" :
           (tflag == FTW_NS) ?  "ns"  : (tflag == FTW_SL) ?  "sl" :
           (tflag == FTW_SLN) ? "sln" : "???",
           ftwbuf->level, (intmax_t) sb->st_size,
           fpath, ftwbuf->base, fpath + ftwbuf->base);
    return 0;           /* To tell nftw() to continue */
}

int
main(int argc, char *argv[])
{
    int flags = 0;

    if (argc > 2 && strchr(argv[2], 'd') != NULL)
        flags |= FTW_DEPTH;
    if (argc > 2 && strchr(argv[2], 'p') != NULL)
        flags |= FTW_PHYS;

    if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags)
            == -1)
    {
        perror("nftw");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

See also

这篇关于目录递归和符号链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆