'~'的标准用法如下:如果单独使用或者后面跟一个'/',那么'~'就被当作当前 用户的home目录,[译者注:事实上'~'就被替换为$HOME环境变量],如果'~'后 直接跟一个用户名,则被替换的就是那个用户的home目录。如果没有合适的匹 配,则shell不会做任何改动。
请注意,有可能一些文件的确是以'~'打头的,不分青红皂白地将'~'替换会使你 的程序无法打开这些文件。一般来说,从shell通过命令行或环境变量传递入程 序的文件名不须要进行替换,因为shell已经替你做好,而程序自己生成的、用 户输入的,或从配置文件中读取的却应该进行替换。
这里是一段用标准string类的C++实现:
string expand_path(const string& path)
{
if (path.length() == 0 || path[0] != '~')
return path;
const char *pfx = NULL;
string::size_type pos = path.find_first_of('/');
if (path.length() == 1 || pos == 1)
{
pfx = getenv("HOME");
if (!pfx)
{
// 我们想替换"~/",但$HOME却没有设置
struct passwd *pw = getpwuid(getuid());
if (pw)
pfx = pw->pw_dir;
}
}
else
{
string user(path,1,(pos==string::npos) ? string::npos : pos-1);
struct passwd *pw = getpwnam(user.c_str());
if (pw)
pfx = pw->pw_dir;
}
// 如果我们不能找到能替换的选择,则将path返回
if (!pfx)
return path;
string result(pfx);
if (pos == string::npos)
return result;
if (result.length() == 0 || result[result.length()-1] != '/')
result += '/';
result += path.substr(pos+1);
return result;
}