递归函数shell脚本

时间:2011-11-21 10:55:58

标签: shell recursion symlink

#!/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(递归)。为什么不扫描所有目录?

(对不起:我的英语很差)

2 个答案:

答案 0 :(得分:6)

  1. 当通配符执行时,不要在反引号中调用ls,并且更可靠,即:

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

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

    1. 使用

      声明变量local
      local file
      

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

    2. 用圆括号代替大括号括起函数。这将使函数在子shell中运行,这不会破坏它的父变量。

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

  5. William Pusell(见另一个答案)还注意到了一件事。 要么 cd进入参数目录,请将其作为路径前缀,但不要同时执行这两项操作。

  6. 有了所有修复,你应该去:

    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 :(得分:1)

如果你这样做:

cd $1
ls $1

除非目录包含具有相同名称的子目录,否则你真的不应该期望看到任何输出。你的意思是:

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