【问题标题】:Robust way to get the user home directory?获取用户主目录的可靠方法?
【发布时间】:2022-10-24 02:35:01
【问题描述】:

$HOME 可以取消设置。因此波浪号~ 是解决方案。 (来源:https://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html

这是我的两个解决方案

HOME="$(cd ~ && pwd)"

HOME="$(cd ~ && ${PWD})"

我应该使用哪个? pwd 还是 ${PWD}?还是您有其他/更好的解决方案?

【问题讨论】:

  • 为什么不只是HOME=~
  • 您是否知道 HOME 可以修改,而 ~ 会反映这一点?这可能是好是坏取决于您所说的“防弹”。
  • HOME=$(POSIXLY_CORRECT=1; PATH=/bin:/usr/bin; \unset -f command; command /bin/rbash -c 'IFS=: read -ra h <<<$(getent passwd $(whoami)); echo "${h[5}"')
  • @user19264607 分配的 RHS 中的扩展不是单词拆分或 globbed。自己试试吧:HOME='/some nonexistent path'; c=~; echo "$c" -> /some nonexistent path
  • @user19264607 是的,如果我们假设 ~ 是可信赖的,则不需要 rbash:HOME=$(POSIXLY_CORRECT=1; \unset HOME; \unset -f builtin; builtin printf '%s' ~)。但也许只要这样做就足够了:unset HOME; HOME=~ 如果不试图防止恶意调用者,则重置

标签: bash unix


【解决方案1】:

如果“防弹”意味着可靠地给出系统对用户主目录的想法,并且不包括试图阻止这一点的用户,那么对于bash,您只需要这样做:

unset HOME
HOME=~

或者

unset HOME
export HOME=~

这是因为,从阅读bash源代码(特别是文件shell.c)来看,当HOME未设置时,~的值一般直接取自pw_dir字段在调用getuid获得的uid上调用getpwuid返回的条目。


可能无法完全防止代码调用者的恶意行为。

【讨论】:

  • 这是最好的方法,但当前代码导致HOME 无法导出。 unset HOME; export HOME=~ 似乎解决了这个问题。
  • @pjh 可以说,如果 HOME 在脚本运行时未设置,那是因为调用者想要那样做,但我想这取决于脚本来决定做什么
【解决方案2】:

也许这样的事情会是合理的防弹

HOME=$(/usr/bin/getent passwd $EUID | /usr/bin/cut -d: -f6)

编辑 1

正如@Shawn 提到的,我们可以使用只读的EUID

编辑 2

正如@Fravadona 注意到的那样,getent 在 macOS 上不可用,那么您可以编写一些小型 C 程序甚至使用 python (python 2.7 仍然是 2022 年中期 macOS 的默认版本)

HOME=$(/usr/bin/python -c 'from __future__ import print_function; import os; import pwd; print(pwd.getpwuid(os.getuid()).pw_dir)')

【讨论】:

  • command getent passwd $EUID(EUID 是只读 bash 变量)
  • @Shawn 好点
  • getent 不可移植;例如,它不适用于 Mac。唯一的防弹方法似乎是编写一个调用 getpwuid 的小 C 代码
  • 也许有趣的是,根据 bash 源代码(如果我没看错的话),如果你想匹配 bash 在设置 ~ 时所做的事情,你应该使用它实际上是 UID
猜你喜欢
  • 2012-10-05
  • 2011-12-16
  • 2013-02-19
  • 2015-03-15
  • 1970-01-01
  • 2012-08-06
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多