2011-04-06 47 views
3

在我的C++应用程序中,我想将工作目录更改为指定的目录。但是当我指定"~/dev/"作为工作目录chdir()失败并返回-1。相反,它在我指定"/home/myusername/dev"时有效。为什么会发生?我该如何解决这个问题(除了检查字符串第一个字符是否是~并用/home/myusername替换它)?为什么chdir(“〜/ dev /”)返回-1?

+0

'CHDIR( “$ HOME的/ dev /”)'也会失败,因为同样的原因。 – MSalters 2011-04-07 09:06:04

回答

4

波浪线(〜)到HOME环境变量的扩展由bash完成。该扩展在传递给chdir命令之前完成。底线是〜由bash处理,而不是由chdir命令处理。所以你不能在chdir()函数调用中使用它。

为了找到其他类型的扩展(和扩展的细节)由bash完成,请检查this link

1

与任何环境变量一样,~的分辨率落入shell中。我不认为你可以在C api函数中使用它。

1

那么当shell在调用任何程序调用之前(即使cd不是程序调用,而是在shell本身中实现的)时,通常由Shell的home目录将其替换为您的shell。

总之:在C中没有办法自动替换〜你的主目录

0

尝试使用$ HOME而是〜只是一个快捷方式到$ HOME。

+2

实际上,如果没有设置$ HOME,shell仍然会扩展到您的主目录,因此它不像$ HOME的快捷方式那么简单。 – 2011-04-06 15:42:57

1

正如前面的答案所述,C库不会替代〜为你。它由shell完成。您不应该假定用户主目录是/ home/myusername,因为这不能被假定。

确定主目录的正确方法是检查HOME环境变量并读取其内容。它通常会被定义,但如果不是,你应该回到使用getpwuid()或类似的调用来获取当前用户的密码条目,这将包括他们的主目录。

2

您可以使用下面的检索何种~有可能扩大到(使用getpwuid):

#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <string.h> 
#include <pwd.h> 

// @prefer_env should be TRUE if you prefer the value of the $HOME 
// environment variable over what is stored in the user's passwd 
char* get_homedir(int prefer_env) 
{ 
    char *found = getenv("HOME"); 
    char *homedir = NULL; 

    if (!prefer_env || !found) 
    { 
     struct passwd *pw = getpwuid(geteuid()); 
     if (pw && pw->pw_dir) found = pw->pw_dir; 
    } 

    if (found) 
    { 
     // I would add error checking 
     homedir = (char*)malloc(strlen(found) + 1); 
     strcpy(homedir, found); 
    } 

    return homedir; 
} 
+0

此代码不检查HOME环境变量,该变量可能会使用不同的值覆盖密码条目中给出的路径。 – 2011-04-06 15:47:20

+0

@Al Riddoch:我总是对这个环境变量持怀疑态度,但这只是基于经验。我会更新我的代码。 – user7116 2011-04-06 15:49:29

+1

对于代表用户以用户身份运行的代码,使用纯粹的用户权限,您应该始终阅读“HOME”,以便为用户提供最大的灵活性。对于从提升特权的角度对用户主目录执行任何类型的权威查找的代码,您应该始终使用'getpwuid_r'。 – 2011-04-06 18:35:22