【问题标题】:Expand variable before tilde在波浪号之前展开变量
【发布时间】:2019-05-03 00:49:06
【问题描述】:

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

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

$ omar=xyz123
$ echo ~$omar

输出看起来不错:

~xyz123

但是如果我输入这个:

$ ls ~$omar

有一个错误:

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

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

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

【问题讨论】:

  • 输出看起来“很好”~xyz123,但它不是xyz123主目录的路径。
  • 所有可能的变通方法都不是很有吸引力。嘀咕诸如eval 之类的滥用术语不会让我受到安全人员的喜爱——这并不能怪他们。
  • 退后一步方式,我想说很少需要别人其他人的主目录,其他人不一定可以访问反正。脚本将由omar 运行,在这种情况下您只需使用~,或者脚本将以root 身份运行,他可以根据需要使用su 变为omar
  • 您可能想改用cdable_vars 选项;添加像omarhome=/home/omar 这样的变量(手动查找一次并将值存储在变量中),然后cd omarhome 将等效于cd "$omarhome"。 (当然,其他命令必须更明确地使用该变量,例如ls "$omarhome"。)

标签: bash shell variable-expansion tilde-expansion


【解决方案1】:

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)"

【讨论】:

  • 例如 home() { getent passwd ${1:?Missing user name} | cut -f6 -d:; } 后跟 -- 例如 ls "$(home $omar)"。当然不如~方便,但最安全。
【解决方案2】:

我会检查"$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\""

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-10
    • 2011-06-06
    • 2019-06-13
    • 2013-03-29
    • 2015-04-28
    • 2019-01-04
    相关资源
    最近更新 更多