我需要得到用户主页文件夹。现在我正在用这个
home=$(eval echo ~$user)$user的内容是由调用方提供的,所以不受信任值。使用eval在这里危险吗?如果是(可能),没有它该如何解决?
发布于 2016-06-26 01:59:44
在拥有它的系统上,您可以使用getent(1)
$ getent passwd "$username" | cut -d: -f 6
/path/to/user/home但是,请确保检查空结果。
发布于 2016-06-26 10:45:04
Tilde扩展在解析过程的早期就会发生,没有几个评估就无法实现您想要的结果。因此,eval是一种解决方案。要实现你想要的目标,最安全的方法是:
eval "$(printf "home=~%q" "$user")"由于使用了%q修饰符,扩展$user将被完全引用,因此这里没有危险(但是不要修改行,您肯定会引入一些安全漏洞)。
您不应该单独使用它:在这一行之后,您必须检查您是否获得了一个有效的目录,例如,
if [[ ! -d $home ]]; then
echo >&2 "Couldn't find home dir for user $user"
exit 1
fi还请考虑user为空时的情况:在这种情况下,home将是运行脚本的用户的主目录。你是否想要这样的行为取决于你。
还有一点需要考虑:当user包含斜杠时:您是否需要此功能取决于您。
现在,根据您想要的特性,最好一次根据某种预定义的模式验证扩展$user,例如,
if [[ $user != [a-z]*([-a-z0-9_]) ]]; then
echo >&2 'Provided user doesn't match valid pattern'
exit 1
fi事实证明,通过这个验证,您的解决方案是安全的。
示例:
在这件事上,一切都很顺利:
$ user=gniourf
$ eval "$(printf "home=~%q" "$user")"
$ declare -p home
declare -- home="/home/gniourf"对于您的代码(使用您的代码,将执行ls,但不是在这里),这种情况将是危险的:
$ user='; ls >&2'
$ eval "$(printf "home=~%q" "$user")"
$ declare -p home
declare -- home="~; ls >&2"https://stackoverflow.com/questions/38034340
复制相似问题