首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不带eval的Tilde展开

不带eval的Tilde展开
EN

Stack Overflow用户
提问于 2016-06-26 01:02:21
回答 2查看 70关注 0票数 3

我需要得到用户主页文件夹。现在我正在用这个

代码语言:javascript
复制
home=$(eval echo ~$user)

$user的内容是由调用方提供的,所以不受信任值。使用eval在这里危险吗?如果是(可能),没有它该如何解决?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-26 01:59:44

在拥有它的系统上,您可以使用getent(1)

代码语言:javascript
复制
$ getent passwd "$username" | cut -d: -f 6
/path/to/user/home

但是,请确保检查空结果。

票数 4
EN

Stack Overflow用户

发布于 2016-06-26 10:45:04

Tilde扩展在解析过程的早期就会发生,没有几个评估就无法实现您想要的结果。因此,eval是一种解决方案。要实现你想要的目标,最安全的方法是:

代码语言:javascript
复制
eval "$(printf "home=~%q" "$user")"

由于使用了%q修饰符,扩展$user将被完全引用,因此这里没有危险(但是不要修改行,您肯定会引入一些安全漏洞)。

您不应该单独使用它:在这一行之后,您必须检查您是否获得了一个有效的目录,例如,

代码语言:javascript
复制
if [[ ! -d $home ]]; then
    echo >&2 "Couldn't find home dir for user $user"
    exit 1
fi

还请考虑user为空时的情况:在这种情况下,home将是运行脚本的用户的主目录。你是否想要这样的行为取决于你。

还有一点需要考虑:当user包含斜杠时:您是否需要此功能取决于您。

现在,根据您想要的特性,最好一次根据某种预定义的模式验证扩展$user,例如,

代码语言:javascript
复制
if [[ $user != [a-z]*([-a-z0-9_]) ]]; then
    echo >&2 'Provided user doesn't match valid pattern'
    exit 1
fi

事实证明,通过这个验证,您的解决方案是安全的。

示例:

在这件事上,一切都很顺利:

代码语言:javascript
复制
$ user=gniourf
$ eval "$(printf "home=~%q" "$user")"
$ declare -p home
declare -- home="/home/gniourf"

对于您的代码(使用您的代码,将执行ls,但不是在这里),这种情况将是危险的:

代码语言:javascript
复制
$ user='; ls >&2'
$ eval "$(printf "home=~%q" "$user")"
$ declare -p home
declare -- home="~; ls >&2"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38034340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档