为什么我的 bash 函数会完成变量的通配符?

why would my bash function complete wildcards for variables?

在我的~/.bash_aliases:

function wtf (){
  echo ;
}

在 bash 进行测试:

>>  wtf t*
testes

卧槽?


既然我知道 bash 在传递它之前会解析我的通配符,我想我会分享我正在构建的函数。这是我的递归删除快捷方式的最终版本:

# delete recursively
function rmr () {
    find . -name "" -type f -delete -exec \
    echo $(tput setaf 1)"deleted >"$(tput setaf 2) {} \; ;
    l;
}

因为您有一个名为 testes 的文件,并且 bash 将 t* 替换为 将参数传递给 wtf() 之前.您可能有多个以 t 开头的文件,但 testes 是第一个,而 wtf 仅回应 </code>。如果将 <code> 替换为 $*,您将看到所有这些。

例如,如果您有文件 testestumble(并且没有其他文件以 t 开头),并发出

wtf t*

bash 会将 t* 替换为 testes tumble(space-分隔),然后评估行

wtf testes tumble

这将导致 wtf 被传递 testes 作为 </code> 和 <code>tumble 作为 </code>。 </p> <p>如果您不希望 shell 进行文件名扩展,您必须在参数周围加上引号,例如 <code>wtf 't*'wtf "t*"。单引号的优点不仅可以避免文件名扩展,还可以避免任何其他类型的扩展(例如参数扩展和变量扩展)。文件名(或路径名)扩展发生在 *?(以及其他),参数和变量扩展发生在 $.

出于同样的原因,你必须引用 echo 的参数,这次用双引号,因为你希望 </code> 的参数扩展发生,但不希望(再次! ) 文件名扩展:</p> <pre><code>function wtf() { echo "" }

man bash是你的朋友,有很多东西要学。

man bash 中,键入 /^EXPANSION/Pathname Expansion。另见 /^QUOTING.

这就是 shell 的工作方式。不是你的函数在做扩展,是 shell 在调用你的函数之前做的。

在函数内部调用函数 时,您需要引用任何要保留的内容(包括通配符 *?)。

wtf() {
  echo ""
}

wtf 't*'