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(递归).为什么不扫描所有目录?
(对不起,我的英语很差)
ls当通配符执行时,不要在反引号中调用并且更可靠,即:
for file in "$1"/*; do
Run Code Online (Sandbox Code Playgroud)变量扩展必须在引号内,否则它将全部落在包括空格在内的任何特殊字符上.你应该使用"$1","$2"和"$1/$file" "$2/$file".
默认情况下,变量在shell中是全局的.因此,递归调用会破坏外部调用的file变量.有两种可能的解决方法:
用变量局部声明变量
local file
Run Code Online (Sandbox Code Playgroud)
在功能的开头.这是"bashishm",即它不是由POSIX shell标准定义的,所以有些shell没有它.
将函数包装在圆括号中而不是大括号中.这将使函数在子shell中运行,这不能破坏它的父变量.
哦,你不需要param1和param2.位置参数是作用域.
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)
我没有测试它,所以可能还有一些问题.