如何在Linux或Unix中查找用户的主目录?

50

如何在Grails中查找任意用户的主目录?在Linux中,通常为/home/user。但是,在一些操作系统中,例如OpenSolaris,路径为/export/home/user。

注:该段英文内容询问如何在Grails中查找任意用户的主目录路径,同时提到了在不同操作系统下该路径可能存在的不同。

你觉得 ~ 目录常量会对你有所帮助吗? - Richard C
你能具体一点吗?你是寻找运行Grails的用户的主目录,还是寻找任意用户名或UID的用户的主目录? - Torsten Marek
系统上的任意用户。 - anon
13个回答

69

通常情况下,您可以使用该语句

String userHome = System.getProperty( "user.home" );

获取任何平台上用户的主目录。有关可以获取的其他内容,请参阅getProperty方法文档。

你可能会遇到某些访问问题,通过使用此解决方法(使用安全策略文件)可以避免这些问题。


应用程序服务器将作为生产用户运行,并位于例如/opt中。这取决于生产账户的设置,可能会或可能不会起作用。因此,询问生产用户的主目录可能不是答案。 - anon
3
OP询问任意用户的主目录,而"user.home"则是当前用户的主目录。如果您从当前用户的主目录转到父目录再转到指定用户名的目录,这种方法是否总是有效? - SpaceTrucker

55

对于类Unix系统,您可能希望使用Shell执行 "echo ~username" (因此使用Runtime.exec()运行{"/bin/sh", "-c", "echo ~username"})。


1
如果您以要查找其主目录的用户身份登录,则运行“echo〜”似乎是解决方法。 - Danny Kopping
14
在这里要十分准确——在 POSIX 规范下,/bin/sh 必须是 Bourne 兼容的 shell,但波浪线扩展(~~user)不是此类 shell 的必需功能之一。Linux 发行版将 BASH 用作 /bin/sh,因此波浪线扩展可以正常工作。如果你在其他某些 UNIX 操作系统中使用 /bin/sh 运行 echo ~,可能会返回波浪线(例如 "~"),而不是主目录路径。 - Santeri Paavolainen
1
这并没有回答问题。他们没有问如何找到自己的主目录,而是问如何找到用户的主目录。 - doug65536
@JoachimSauer 啊,好的,我的错。我没有意识到“用户名”是要获取其目录路径的用户名的占位符。我在我的系统上尝试了一下,它确实可以工作。谢谢。 - doug65536
如果你和我一样不是Java开发人员,请看这里:https://gist.github.com/zambon/9140388 - Henrique Zambon
显示剩余4条评论

7

在Java中试试这个:

System.out.println("OS: " + System.getProperty("os.name") + ", USER DIRECTORY: " + System.getProperty("user.home"));

5

对于任意用户,作为Web服务器:

private String getUserHome(String userName) throws IOException{
    return new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(new String[]{"sh", "-c", "echo ~" + userName}).getInputStream())).readLine();
}

3

我猜您想找到另一个用户的主目录。显然,获取“user.home”属性是获取当前用户主目录的最简单方法。

要获取任意用户的主目录,需要在命令行中稍微用点技巧:

String[] command = {"/bin/sh", "-c", "echo ~root"}; //substitute desired username
Process outsideProcess = rt.exec(command);
outsideProcess.waitFor();
String tempResult;
StringBuilder sb = new StringBuilder();
while((tempResult = br.readLine()) != null) sb.append(tempResult);
br.close();
return sb.toString().trim();

现在从技术上讲,我们应该有一个线程等待stdout和stderr,以便缓冲区不会填满并锁定进程,但我希望缓冲区至少能够容纳一个用户名。此外,您可能需要检查结果是否以〜root(或您使用的任何用户名)开头,以确保用户存在且已正确评估。
希望这可以帮助您。如果有用,请投票支持此答案,因为我是SO的新贡献者,可以使用积分。

3
如果您正在尝试针对无法硬编码的用户名执行此操作,则可能会很具有挑战性。当然,echo ~rbronosky 将告诉您到我的主目录的路径 /home/rbronosky,但是如果 rbronosky 存储在变量中呢?如果您执行 name=rbronosky; echo ~$name,则会得到 ~rbronosky
以下是一个真实案例及其解决方案:
您必须通过 sudo 运行用户脚本。该脚本必须访问用户的主文件夹。您不能引用 ~/.ssh,否则它将扩展为 /root/.ssh。相反,您可以执行以下操作:
# Up near the top of your script add
export HOME=$(bash <<< "echo ~${SUDO_USER:-}")
# Then you can use $HOME like you would expect
cat rsa_key.pub >> $HOME/.ssh/authorized_keys

这个脚本的美妙之处在于,如果不以sudo身份运行,则$SUDO_USER为空,因此基本上与执行“echo~”相同。它仍然像你期望的那样工作。

如果您使用set -o nounset,并且您应该使用,则变量引用${SUDO_USER:-}将默认为空,而$SUDO_USER${SUDO_USER}会报错(因为未设置),如果没有通过sudo运行。


谢谢。我在找什么来着?这在Shell脚本中很有用。 - riderchap
三个尖括号<<<的含义是什么?通过搜索重定向,这里或三个尖括号均未能提供信息,我在印刷参考资料中也找不到任何相关内容。 - Bennett Brown
1
在 http://www.tldp.org/LDP/abs/html/abs-guide.html 的第19.1节中,它被描述为“here string”。 - Bennett Brown
@BBrown,我很高兴你找到了它。Here字符串是避免不必要的子shell的一种方式。我很惊讶它们在“echo Awards”中没有被提到。http://partmaps.org/era/unix/award.html#echo 现在你知道了herestrings(像heredocs一样),试想一下如果没有它会有多难以阅读... export HOME=$(echo "echo ~$SUDO_USER" | bash) “echo echo?什么?” - Bruno Bronosky

3
您可以使用环境变量$HOME来实现此目的。

$HOME 根据登录的用户而变化。我不明白它如何用于查找 任意 用户的主目录。 - Sebastian Simon

3
如果你想找到特定用户的主目录,我不认为你能直接做到。
当我之前需要从Java中执行此操作时,我必须编写一些JNI本地代码,包装UNIX的getpwXXX()调用系列。

2

eval echo ~$SUDO_USER

这可能有效。


1

在类UNIX系统中查找用户FOO的主目录,请使用~FOO。对于当前用户,请使用~


3
这只能被shell解释,而不是内核/库。 - Joachim Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接