这是我用来测试它的代码。 它适用于普通目录,但不适用于在sshfs下安装的目录。 我的目标是使用这些方法 https://github.com/jlettvin/Greased-Grep 旨在允许全局模糊搜索 必须存在的关键字和必须缺席的关键字。
#include <iostream>
#include <string>
#include <functional>
#include <dirent.h>
using std::cout;
using std::endl;
using std::string;
using std::function;
bool neither (const char* path)
{
bool ret = (path != nullptr);
if (ret)
{
if (path[0] == '.')
{
if (path[1] == '\0') ret = false;
if (path[1] == '.' && path[2] == '\0') ret = false;
}
}
return ret;
}
void walk (const string &path, function<void (const string &)> talk)
{
if (auto dir = opendir (path.c_str ())) {
while (auto f = readdir (dir)) {
auto name = f->d_name;
auto type = f->d_type;
if (neither (name))
{
switch (type)
{
case DT_DIR: walk (path + name + "/", talk); break;
case DT_REG: talk (path + name ); break;
}
}
}
closedir(dir);
}
}
int main (int argc, char** argv)
{
walk ("./", [](const string &path) { cout << path << endl; });
return 0;
}
答案 0 :(得分:2)
您需要review the following documentation in the Linux's readdir(3)
manual page:
unsigned char d_type; /* Type of file; not supported by all filesystem types */
具体来说,您的注意力集中在&#34;所有文件系统类型都不支持&#34;一部分。
您的代码需要设置d_type
。但是,readdir(3)
并不保证会出现这种情况。
d_type
的一个可能值是:
DT_UNKNOWN The file type could not be determined.
应准备好处理所有可能性的代码必须明确检查DT_UNKNOWN
,如果是,则将d_name
附加到目录名称stat()
文件名,然后抓住文件类型从那里。
d_type
是一种捷径。如果它设置好了。你马上就可以了。如果没有,你必须努力去做。
sshfs
显然不支持从d_type
返回readdir(3)
。希望sshfs
实现stat()
。
P.S。,除了目录和常规文件之外,还有其他一些特殊类型,您可能需要或不必处理(假设sshfs
甚至可以提供给您)。这是你需要自己调查的东西。
答案 1 :(得分:0)
我有我想要操作的代码。
经过对各种旗帜,条件和情况的各种敏感性的大量试验,我决定完全简单。
我将一切都视为目录和文件。如果它不是目录,我会检测并忽略所有错误并继续。如果它是一个目录,那么我打开它并搜索其内容以寻找我想要的内容。这是Greased-Grep的一个优势,其目标是找到匹配模式的东西。文件名就像它们的内容一样。
所以,我的答案是,我不关心失败。我只关心成功,所以我在没有任何测试的情况下解雇失败。
当降序sshfs挂载目录时,这可以正常工作。
任何对此代码看起来如何感兴趣的人都可以关注我的github: https://github.com/jlettvin/Greased-Grep/blob/master/gg.cpp
以下是显着的代码:
void walk (const string& a_path)
{
// Don't attempt to assess validity of filenames... just fail.
// Treat directories like files and search filenames in directories.
// This enables gg to work on sshfs mounted filesystems.
auto d{a_path};
auto s{d.size ()};
if (s && d[s - 1] == '/') d.resize (s-1);
errno = 0;
if (auto dir = opendir (d.c_str ()))
{
while (!errno)
{
if (auto f = readdir (dir))
{
if (auto p = f->d_name)
{
if (auto q = p)
{
if (!(*q++ == '.' && (!*q || (*q++ == '.' && !*q))))
{
auto e = d + "/" + p;
walk (e);
mapped_search (e.c_str ());
errno = 0;
}
}
else break;
}
else break;
}
else break;
}
}
}