Bash 传递字符串值将无法找到该文件

Bash 传递字符串值将无法找到该文件,bash,Bash,我编写了一个shell,它将尝试将文件从文件路径收集到当前目录(如果存在): collect_file() { fpath=$1 echo $fpath if [ -e $fpath ]; then fname=`basename $fpath` `cp $1 $fname` retval=$? if [ $retval == 0 ]; then echo "Collect file '$fpath'" else ec

我编写了一个shell,它将尝试将文件从文件路径收集到当前目录(如果存在):

collect_file() {
  fpath=$1
  echo $fpath
  if [ -e $fpath ]; then

    fname=`basename $fpath`
    `cp $1 $fname`
    retval=$?
    if [ $retval == 0 ]; then
      echo "Collect file '$fpath'"
    else
      echo "Error: fail to copy file '$fpath'"
    fi

  else
    echo "Error: file '$fpath' not found"
  fi  
}
现在,如果我传递一个空值
~/.gitconfig
,它将成功,但是当我传递一个字符串值
“~/.gitconfig”
,它将失败

collect_file ~/.gitconfig        # will succeed to copy the file
collect_file "~/.gitconfig"      # will fail
显示:

# results for bare value
/Users/Xaree/.gitconfig
Collect file '/Users/Xaree/.gitconfig'

# results for string value
~/.gitconfig
Error: file '~/.gitconfig' not found

为什么以及如何修复它?

以下内容涉及用户主目录中的文件:

~/.gitconfig
相比之下,以下引用名为
~
的目录中的文件:

"~/.gitconfig"
当shell执行tilde扩展时,
~/
被解释为主目录。外壳仅在<代码>打开时执行平铺扩展不带引号。如果字符串被引用,则
~
仅表示
~
,而不表示其他内容

例子 请注意,仅对以下三种语句中的一种执行波浪形展开:

$ echo "~/.bashrc"
~/.bashrc
$ echo ~"/.bashrc"
~/.bashrc
$ echo ~/".bashrc"
/home/john1024/.bashrc
强制分片扩展 由shell实现的Tilde扩展提供了许多特性和许多特殊情况。我们可以使用
eval
强制进行一般的tilde扩展,但这会带来许多安全问题。但是,就基本情况而言,我们可以用
$HOME/
安全地替换变量中的
~/
,如下所示:

fpath="${fpath/~\//$HOME\/}"
上面的问题是,即使字符串不是以
~/
开头,它也会替换第一次出现的
~/
。为了避免这种情况,我们可以使用:

[ "${fpath#\~/}" != "$fpath" ] && fpath="${fpath/~\//$HOME\/}"

此测试确保字符串在进行替换之前以
~/
开头。

谢谢。有没有办法解决这个问题@李岡諭 shell抑制引用字符串的某些扩展通常应被视为一种特性,而不是bug。但是,我只是在答案中添加了代码,显示了如果需要,如何强制进行简单的平铺扩展。