Как заменить домашний каталог тильдой? Linux

В настоящее время я делаю оболочку на C ++, и я смог вывести абсолютный каталог в виде приглашения с помощью getcwd (), однако, когда пользователь достигает домашнего каталога, я хотел бы вывести тильду вместо домашнего каталога.

Так например вместо

[bb @ bbmachine bb]

Я хотел бы вывести

[bb @ bbmachine ~]

Как бы я сделал что-то подобное?

0

Решение

Читайте сначала о подстановка, особенно шарик (7). Для расширение пути, начинающегося с тильды ~ рассматривать wordexp (3) а также шарик (3).

Чтобы показать путь, начинающийся с домашнего каталога, вам нужно получить этот домашний каталог. Вы могли бы использовать GETENV (3) лайк getenv("HOME") (есть редкие патологические случаи, когда это может потерпеть неудачу) или getpwuid (3) (или даже getpw (3)) по итогам getuid (2). Домашний каталог (когда getpwuid успешно) дается pw_dir поле. Смотрите также Учетные данные (7) (а также execve (2)…)

Есть редкие патологические случаи, когда getenv("HOME") а также getpwuid(getuid()) дать сбой или дать непоследовательные результаты (о домашнем каталоге пользователя). Я считаю, что вы должны обнаружить сбой, но вы можете не заботиться о несоответствии. Смотрите также Environ (7). Вы могли бы даже рассмотреть специфический GNU secure_getenv (3).

Кстати, вы можете кэшировать домашний каталог, то есть вычислить его один раз в вашей оболочке. Вряд ли это будет часто меняться.

Вы также можете решить канонизировать путь, используя Realpath (3).

У вас наверняка есть угловые шкафы: вы хотите показать /home/john/../mary/ как ~/../mary, как /home/mary/, как ~mary, (или даже оставить как /home/john/../mary) если ваш процесс запущен john UID? (и оба john а также mary существуют как имена пользователей в PASSWD (5) с домашними каталогами /home/john/ а также /home/mary/). И что насчет /home/john/../../proc/$$/maps (увидеть Proc (5))?

Вам нужно решить, как вы будете справляться с этими угловыми или патологическими случаями, и документ поведение вашей оболочки.

(упомянутые функции имеют C API, вы можете использовать extern "C" в вашем коде C ++)

3

Другие решения

Именно то, что сказал @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 ваши друзья.Ссылка на строку

2

Вы могли бы использовать 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
1
По вопросам рекламы [email protected]