递归函数shell脚本

发布于 2024-12-17 08:19:59 字数 402 浏览 0 评论 0原文

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

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

#!/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

If I execute this script, that it call self (recursive). Why not scan all directories?

(excuse me: my english is poor)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

似梦非梦 2024-12-24 08:20:00
  1. 当通配符可以使用并且更可靠时,不要在反引号中调用ls,即:

    用于“$1”/* 中的文件;做
    
  2. 变量扩展必须位于内部 引号,否则它将全部落在任何特殊字符(包括空格)上。您应该使用 "$1""$2""$1/$file" "$2/$file"

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

    1. 将变量声明为局部变量

      本地文件
      

      位于函数的开头。这是“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"

我没有测试它,所以可能仍然存在一些问题。

  1. Don't call ls in backquotes when wildcard will do and is more reliable, that is:

    for file in "$1"/*; do
    
  2. The variable expansions have to be inside the quotes or it will all fall down on any special character including space. You should use "$1", "$2" and "$1/$file" "$2/$file".

  3. Variables are global in shell by default. So the recursive call clobbers the outer call's file variable. There are two possible workarounds:

    1. Declare the variable local with

      local file
      

      at the beginning of the function. This is "bashishm", i.e. it's not defined by POSIX shell standard, so some shells don't have it.

    2. Wrap the function in round parenthesis instead of curly brackets. That will make the function run in a subshell, which can't clobber it's parents's variables.

  4. Oh, you don't need the param1 and param2. The positional parameters are scoped.

  5. William Pusell (see the other answer) notices one more thing. Either cd into the argument directory or prefix it to the path, but don't do both.

With all the fixes you should get to:

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"

I didn't test it, so there may still be some problem left.

戒ㄋ 2024-12-24 08:20:00

如果这样做:

cd $1
ls $1

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

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

If you do:

cd $1
ls $1

you really shouldn't expect to see any output unless the directory contains a sub directory with the same name. You meant:

cd $1
for file in $(ls .) ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文