How to replace the home directory with a tilde? Linux

可紊 提交于 2019-12-11 20:08:10

问题


I'm currently making a shell in C++ and I've been able to output the absolute directory as the prompt with getcwd(), however when the user reaches the home directory I would like to output a tilde instead of the home directory.

So for example instead of

[bb@bbmachine bb]

I would like to output

[bb@bbmachine ~]

How would I do something like that?


回答1:


Read first about globbing, notably glob(7). For the expansion of path starting with tilde ~ consider wordexp(3) and glob(3).

For showing a path starting with the home directory, you need to get that home directory. You could use 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)...)

There are rare pathological cases where getenv("HOME") and getpwuid(getuid()) fail or give unconsistent results (about the user's home directory). I believe you should detect failure, but you might not care about inconsistency. See also environ(7). You could even consider the GNU specific secure_getenv(3).

BTW, you could cache the home directory, i.e. compute it once in your shell. It is unlikely to change often.

You could also decide to canonicalize a path using realpath(3).

You certainly have corner cases: do you want to display /home/john/../mary/ as ~/../mary, as /home/mary/, as ~mary, (or even leave it as /home/john/../mary) assuming your process is running under john uid? (and both john and mary exist as user names in passwd(5) with home directories /home/john/ and /home/mary/). And what about /home/john/../../proc/$$/maps (see proc(5))?

You need to decide how you'll handle these corner or pathological cases, and document the behavior of your shell.

(the functions mentioned have a C API, you might want to use extern "C" in your C++ code)




回答2:


Exactly what @TheDude said. Here's some pseudocode.

#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);

This should give you the right idea, but remember, documentation and Google are your friends.String Reference




回答3:


You could use wordexp something like this:

#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';
}

Output:

~/wibble


来源:https://stackoverflow.com/questions/48759799/how-to-replace-the-home-directory-with-a-tilde-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!