如何用代字号替换主目录? Linux

How to replace the home directory with a tilde? Linux

我目前正在用 C++ 编写 shell 并且我已经能够使用 getcwd() 将绝对目录作为提示输出,但是当用户到达主目录时我想输出波浪号而不是主目录。

例如

[bb@bbmachine bb]

我要输出

[bb@bbmachine ~]

我该怎么做?

正是@TheDude 所说的。这是一些伪代码。

#include "pwd.h"
#include <string>
string home=getenv("HOME");
int location=yourPathString.find(home);
length=home.length();
originalLength=yourPathString.length();
string newString=yourPathString.substr(0,location);
newString+= "~";
newString+= yourPathString.substr(location+length,originalLength);

这应该会给您正确的想法,但请记住,文档和 Google 是您的朋友。String Reference

先阅读有关 globbing, notably glob(7). For the expansion of path starting with tilde ~ consider wordexp(3) and glob(3) 的内容。

要显示以主目录开头的路径,您需要获取该主目录。您可以使用 getenv(3) like getenv("HOME") (there are rare pathological cases where that could fail) or getpwuid(3) (or even getpw(3)) on the result of getuid(2). The home directory (when getpwuid succeeds) is given by the pw_dir field. See also credentials(7) (and execve(2)...)

在极少数情况下,getenv("HOME")getpwuid(getuid()) 会失败或给出不一致的结果(关于用户的主目录)。我相信你应该检测失败,但你可能不关心不一致。另见 environ(7). You could even consider the GNU specific secure_getenv(3).

顺便说一句,您可以缓存主目录,即在 shell 中计算一次。它不太可能经常更改。

您还可以决定使用 realpath(3).

规范化路径

你肯定有极端情况:你想将 /home/john/../mary/ 显示为 ~/../mary,显示为 /home/mary/,显示为 ~mary,(甚至保留为 /home/john/../mary) 假设你的进程是 运行 在 john uid 下? (johnmary 都作为用户名存在于 passwd(5) with home directories /home/john/ and /home/mary/). And what about /home/john/../../proc/$$/maps (see proc(5) 中)?

您需要决定如何处理这些极端情况或病态情况,并记录您shell.

的行为

(提到的函数有一个 C API,你可能想在你的 C++ 代码中使用 extern "C"

你可以使用 wordexp 这样的东西:

#include <wordexp.h>

// put all the horrible bits into a function
std::string wordexp(std::string var, int flags = 0)
{
    wordexp_t p;
    if(!wordexp(var.c_str(), &p, flags))
    {
        if(p.we_wordc && p.we_wordv[0])
            var = p.we_wordv[0];
        wordfree(&p);
    }
    return var;
}

int main()
{
    auto const HOME = wordexp("~");

    std::string path = "/home/galik/wibble";

    if(path.find(HOME) == 0)
        path.replace(0, HOME.size(), "~");

    std::cout << path << '\n';
}

输出:

~/wibble