如何将主目录替换为波浪号?Linux

How to replace the home directory with a tilde? Linux

本文关键字:Linux 主目录 替换      更新时间:2023-10-16

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

所以例如,而不是

[bb@bbmachine bb]

我想输出

[bb@bbmachine ~]

我该怎么做这样的事情?

首先阅读有关通配的信息,尤其是 glob(7)。对于以波浪号开头的路径的扩展~请考虑 wordexp(3) 和 glob(3)。

要显示以主目录开头的路径,您需要获取该主目录。你可以使用 getenv(3) 像getenv("HOME")(在极少数病理情况下可能会失败)或 getpwuid(3) (甚至 getpw(3)) 来计算 getuid(2) 的结果。主目录(getpwuid成功时)由pw_dir字段给出。另请参阅凭据(7)(和 execve(2)...)

在极少数情况下,getenv("HOME")getpwuid(getuid())失败或给出不一致的结果(关于用户的主目录)。我相信你应该检测失败,但你可能不关心不一致。另见环境(7)。你甚至可以考虑GNU特定的secure_getenv(3)。

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

你也可以决定使用 realpath(3) 规范化路径。

您当然有极端情况:假设您的进程在johnuid 下运行,您是否希望将/home/john/../mary/显示为~/../mary/home/mary/~mary(甚至将其保留为/home/john/../mary)?(johnmary都作为用户名存在于 passwd(5) 中,主目录为/home/john//home/mary/)。那么/home/john/../../proc/$$/maps呢(参见proc(5))?

你需要决定如何处理这些角落或病理病例,并记录你的外壳的行为。

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

正是@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);

这应该给你正确的想法,但请记住,文档和谷歌是你的朋友。字符串引用

你可以使用 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