递归函数shell脚本

Gáb*_*rga 2 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
Run Code Online (Sandbox Code Playgroud)

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

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

Jan*_*dec 6

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

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

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

    1. 用变量局部声明变量

      local file
      
      Run Code Online (Sandbox Code Playgroud)

      在功能的开头.这是"bashishm",即它不是由POSIX shell标准定义的,所以有些shell没有它.

    2. 将函数包装在圆括号中而不是大括号中.这将使函数在子shell中运行,这不能破坏它的父变量.

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

  5. William Pusell(见另一个答案)注意到了另外一件事.无论是 cd到参数目录或者其前缀路径,但不要两者都做.

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

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"
Run Code Online (Sandbox Code Playgroud)

我没有测试它,所以可能还有一些问题.