使用~作为Bash路径变量导致“没有这样的文件或目录”错误

3

If I do this:

ls ~/Dev/Project/Assets/_Core/

我得到了一个超级棒的目录列表!太好了!但是如果我这样做:

assetsPath=$(head -n 1 .config | perl -ne 'print if s/^assets=(.*)/\1/g')
echo $assetsPath
ls $assetsPath

我得到:
~/Dev/Project/Assets/_Core/ # this was the variable value from the echo
ls: ~/Dev/Project/Assets/_Core/: No such file or directory

我甚至尝试使用${assetsPath},但那也没有起作用?

9
在变量展开之前会发生~(波浪线)扩展。你不能将它放在一个变量里。使用$HOME或者不要把它放在变量中。 - Etan Reisner
嗯,我想在配置中支持它,但我可以很容易地用$HOME替换字符串中的~。 - brandonscript
你真的不想这样做。它并不等同于此。这是一个shell的事情(它不仅仅是扩展到$HOME)。只需让他们将值写出来(或者如果您已经在那里扩展了shell变量,请让他们使用$HOME)。 - Etan Reisner
1
@remus,除非在eval之前添加if [[ $assetsPath == *[^/.~a-zA-Z0-9]* ]]; then echo "preventing bad things from happening!!"; exit 1; fi,否则此解决方案不合法。 - that other guy
1
是的,eval 只有在你的需求中包括“添加一个巨大的安全漏洞”(或者像 @thatotherguy 建议的那样仔细验证传递给它的值,尽管我无法立即评估该验证是否足够)时才是一个“解决方案”。 - Etan Reisner
显示剩余2条评论
1个回答

3
作为部分解决方案:
assetsPath=${assetsPath//'~'/$HOME}

这段内容没有涉及到~username的扩展;如果你的assetsPath使用了它,那么你需要更多的逻辑(我认为我已经在另一个StackOverflow答案中添加了它;正在寻找问题)。
它也没有解决非首位位置的波浪号~,在那里它不应该被展开。为了处理这两种特殊情况,我将会自我剽窃一下:链接
expandPath() {
  local path
  local -a pathElements resultPathElements
  IFS=':' read -r -a pathElements <<<"$1"
  : "${pathElements[@]}"
  for path in "${pathElements[@]}"; do
    : "$path"
    case $path in
      "~+"/*)
        path=$PWD/${path#"~+/"}
        ;;
      "~-"/*)
        path=$OLDPWD/${path#"~-/"}
        ;;
      "~"/*)
        path=$HOME/${path#"~/"}
        ;;
      "~"*)
        username=${path%%/*}
        username=${username#"~"}
        IFS=: read _ _ _ _ _ homedir _ < <(getent passwd "$username")
        if [[ $path = */* ]]; then
          path=${homedir}/${path#*/}
        else
          path=$homedir
        fi
        ;;
    esac
    resultPathElements+=( "$path" )
  done
  local result
  printf -v result '%s:' "${resultPathElements[@]}"
  printf '%s\n' "${result%:}"
}

...然后:

assetsPath=$(expandPath "$assetsPath")

谢谢。好多了。我不需要支持~username的扩展,所以这样就可以。 - brandonscript
@EtanReisner,...其中一个被删除是因为准确性问题,对吧? - Charles Duffy
@EtanReisner,嗯——我不能就这样放任它;我会再多付出一些努力。 - Charles Duffy
@EtanReisner,我相信我已经解决了你提到的问题。 - Charles Duffy
1
结果我也无法放任不管...所以我做了这个:https://github.com/deryni/expandTilde.sh - Etan Reisner
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接