【问题标题】:Tilde in path doesn't expand to home directory路径中的波浪号不会扩展到主目录
【发布时间】:2011-08-10 12:45:09
【问题描述】:

假设我有一个名为Foo 的文件夹位于/home/user/(我的/home/user 也由~ 表示)。

我想要一个变量

a="~/Foo" 然后做

cd $a

我明白了 -bash: cd: ~/Foo: No such file or directory

但是,如果我只是做cd ~/Foo 它工作正常。关于如何让它工作的任何线索?

【问题讨论】:

标签: bash syntax tilde-expansion


【解决方案1】:

您可以这样做(在变量赋值期间不带引号):

a=~/Foo
cd "$a"

但在这种情况下,变量$a 不会存储~/Foo,而是扩展形式/home/user/Foo。或者你可以使用eval:

a="~/Foo"
eval cd "$a"

【讨论】:

  • 谢谢! eval cd 有效。我确实想保持“〜/ Foo”完好无损,所以这个解决方案有效。起初我尝试了 cd eval $a 但没有奏效。
  • 对于使用eval 的常见警告也应在此处突出显示。 永远不要对您尚未清理或以安全方式构建自己的数据运行eval
  • 不幸的是,如果目录名称包含空格,这将不起作用。 a="~/dir with spaces"; eval cd "$a" => -bash: cd: /Users/jack/dir: No such file or directory :-(
  • @duthen:你可以使用丑陋的变体cd "$(eval echo "$a")"
  • 正确正确的写法是a=~/dir\ with\ spaces或等效的a=~/"dir with spaces"
【解决方案2】:

您可以使用$HOME 代替波浪号(波浪号由shell 扩展为$HOME 的内容)。 示例:

dir="$HOME/Foo";
cd "$dir";

【讨论】:

  • 如果你的名字不是“John F.”,引号的好处是什么?为什么要用分号?
  • 感谢您提到波浪号实际上扩展为 $HOME,我认为无论如何它更具可读性。
  • @userunknown,如果你把引号去掉,你就是在告诉外壳做更多的事情,而这些事情都有失败的案例。例如,如果有人将 IFS=/ 设置为读取斜杠分隔的输入,那么即使没有空格,cd $dir 也会出现异常行为。扩展不带引号的字符串告诉 shell 对字符串进行拆分和全局扩展。为什么要编写代码来指示 shell 执行您不希望它执行的操作?
【解决方案3】:

虽然这个问题只是寻求一种解决方法,但它被列为许多询问为什么会发生这种情况的问题的重复项,所以我认为值得给出解释。根据https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06

扩词顺序如下:

应从头到尾执行波浪号扩展、参数扩展、命令替换和算术扩展。

当 shell 计算字符串 cd $a 时,它首先执行波浪号扩展(这是一个无操作,因为 $a 不包含波浪号),然后它将 $a 扩展为字符串 ~/Foo,这是最终作为参数传递给cd 的字符串。

【讨论】:

    【解决方案4】:

    更强大的解决方案是使用类似 sed 甚至更好的 bash 参数扩展:

    somedir="~/Foo/test~/ing";
    cd "${somedir/#\~/$HOME}"
    

    或者如果你必须使用 sed,

    cd $(echo "$somedir" | sed "s#^~#$HOME#")
    

    【讨论】:

    • 不幸的是,如果您尝试引用其他人的主目录,这将不起作用。 somedir="~jack/TMP"; cd ${somedir/#\~/$HOME} => -bash: cd: /Users/jackjack/TMP: No such file or directory :-(
    【解决方案5】:

    如果你使用双引号, ~ 将作为 $a 中的那个字符。

    cd $a 不会扩展 ~,因为 shell 不会扩展变量值。

    解决办法是:

    eval "cd $a"

    【讨论】:

      猜你喜欢
      • 2013-07-10
      • 2017-02-28
      • 2016-11-05
      • 1970-01-01
      • 2011-06-06
      • 2013-03-29
      • 2019-04-30
      相关资源
      最近更新 更多