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

时间:2016-03-20 11:00:59

标签: bash function alias

在我的〜/ .bash_aliases中:

function wtf (){
  echo $1;
}

在bash中测试:

>>  wtf t*
testes

WTF?

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

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

2 个答案:

答案 0 :(得分:4)

这就是炮弹的运作方式。它不是你进行扩展的功能,它是在调用你的函数之前执行它的shell。

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

wtf() {
  echo "$1"
}

wtf 't*'

答案 1 :(得分:3)

因为您有一个名为testes的文件,而bash会将t*替换为之前将参数传递给wtf()。您可能有几个以t开头的文件,但testes是第一个,wtf仅回显$1。如果您将$1替换为$*,则会看到所有这些内容。

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

wtf t*

bash会将t*替换为testes tumble(以空格分隔),然后评估该行

wtf testes tumble

wtf testes $1tumble $2传递给wtf 't*'

如果您不希望shell进行文件名扩展,则必须在参数周围添加引号,例如wtf "t*"*。单引号的优点是不仅可以避免文件名扩展,还可以进行任何其他类型的扩展(例如参数扩展和变量扩展)。文件名(或路径名)扩展发生在?$(以及其他),参数和变量展开echo

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

man bash

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

/^EXPANSION内,输入/Pathname Expansion/^QUOTING。另请参阅#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(){ printf("Programme qui change de PID toutes les deux secondes \n"); pid_t fils; while(1){ printf("I'm %d\n",(int)getpid()); sleep(5); fils = fork(); if(fils < 0){ perror("Fork child \n"); exit(1); } else if (fils ==0 ) exit(0); } return 0; }