2011-11-21 98 views
2
#!/bin/sh 

param1=$1 
param2=$2 

recursive(){ 
    mkdir -p $2 
    cd $1 
    for file in `ls $1`; do 
     [ $file = "." -o $file = ".." ] && continue 
     [ -d $file ] && recursive $1"/"$file $2"/"$file 
     [ -f $file ] && ln -s $1"/"$file $2"/"$file 
    done 
} 

recursive $param1 $param2 

如果我执行这个脚本,它会调用self(递归)。为什么不扫描所有目录?递归函数shell脚本

(原谅我:我的英语很差)

回答

6
  1. 不要叫ls在反引号时通配符会做的,是更可靠的,那就是:

    for file in "$1"/*; do 
    
  2. 变量扩展必须是里面的这个引号,否则它会掉落在任何特殊字符上,包括空格。您应该使用"$1""$2""$1/$file" "$2/$file"

  3. 默认情况下,变量在shell中是全局的。因此递归调用会暴露外部调用的变量file。有两种可能的解决方法:

    1. 声明局部变量与

      local file 
      

      在函数的开始。这是“bashishm”,即它不是由POSIX shell标准定义的,所以有些shell没有它。

    2. 将函数换成圆括号而不是大括号。这将使该函数运行在一个子shell中,它不能破坏父母的变量。

  4. 哦,你不需要param1param2。位置参数是作用域的。

  5. William Pusell(查看其他答案)注意到一件事。 要么将​​光盘放入参数目录将其前缀添加到路径中,但不要同时执行这两个操作。

与所有的补丁,你应该去:

recursive() (
    mkdir -p "$2" 
    for file in "$1"/*; do 
     [ "$file" = "." -o "$file" = ".." ] && continue 
     [ -d "$file" ] && recursive "$1/$file" "$2/$file" 
     [ -f "$file" ] && ln -s "$1/$file" "$2/$file" 
    done 
) 

recursive "$1" "$2" 

我没有测试它,所以有可能还是留下了一些问题。

1

如果你这样做:

 
cd $1 
ls $1 

你真的不应该期望看到任何输出,除非目录中,有一个同名的子目录。你的意思是:

 
cd $1 
for file in $(ls .) ...