3

我确定以前有人问过这个问题,但我找不到任何东西。我们在共享机器上有难以理解的登录名,并希望使用 shell 变量来替换难以记住的登录名来代替人们的真实姓名。

例如,假设 Omar 的登录名是 xyz123。我可以做这个:

$ omar=xyz123
$ echo ~$omar

并且输出看起来不错:

~xyz123

但如果我输入这个:

$ ls ~$omar

有一个错误:

ls: cannot access ~xyz123: No such file or directory

我认为这是因为波浪号扩展发生在变量扩展之前,但无法弄清楚如何解决这个问题。

尽管我不确定,但也许这个答案是相关的: How to manual expand a special variable (ex: ~ tilde) in bash

4

2 回答 2

3

bash在变量之前扩展波浪号。请参阅https://www.gnu.org/software/bash/manual/bash.html#Shell-Expansions

shell 将查看文字字符$ o m a r 是否是登录名。因为它们不是,所以波浪号没有扩大。shell 最终将$omar其视为一个变量并替换它。然后它会将扩展的单词~xyz123交给echo它来打印它。

同样,它把这个词~xyz123交给ls. 由于 ls 不进行自己的波浪号扩展,它会在当前目录中查找以~xyz123文字波浪号命名的文件。由于这样的文件不存在,您会收到该错误。

如果要ls ~$var列出文件,则需要eval ls ~$var. 或者,由于 eval 被认为随意使用非常不安全,您可以这样做:

ls "$(getent passwd "$omar" | cut -d: -f6)"
于 2018-11-30T21:04:06.740 回答
0

我会检查是否"$omar"是有效用户,id然后使用eval强制双重扩展。所以要防范邪恶eval,然后去做。

if ! id "$omar" >/dev/null 2>&1; 
   echo "Error: user with the name $omar does not exist!" >&2
   exit 1
fi
eval echo "\"~$omar\""
于 2018-11-30T21:08:20.593 回答