shell bash递归似乎无缘无故地停止

jutyujz0  于 2023-08-07  发布在  Shell
关注(0)|答案(1)|浏览(119)

我正在尝试编写一个脚本来做到这一点:假设我有一个名为testdir的目录,它看起来像这样:

**testdir**/
├── **jfjfjddsdsdsds** (directory)
├── jfjfjfjf (file)
├── kdskskk  
├── kkkkkkkkk
├── **sadadasad**
│   ├── assd
│   ├── **kakak**
│   ├── **ksja**
│   ├── **lklksl**
│   └── lskal
└── **skdjsjlsj**
    ├── **djfldjlfjd**
    │   ├── eiuru
    │   ├── rhhrhshs
    │   ├── rhrhshs
    │   └── shhdshsd
    ├── jjskskk
    ├──** kdjskdjfks**
    ├── kjjrjjrj
    └── kjskjd

字符串
文件名是完全随机的,我想写一个脚本,它需要一个目录路径,并重命名每个子目录和每个文件,看起来像这样:

**testdir**/
├── **dir1**
├── file1
├── file2  
├── file3
├── **dir2**
│   ├── file1 
│   ├── **dir1**
│   ├── **dir2**
│   ├── **dir3**
│   └── file2
└── **dir3**
    ├── **dir1**
    │   ├── file1
    │   ├── file2
    │   ├── file3
    │   └── file4
    ├── file1
    ├──** dir2**
    ├── file2
    └── file3


所以它按顺序重命名每个目录-第一个成为“dir 1”,第二个成为“dir 2”,等等。对于文件也是一样的-“file 1”,“file 2”,它还从开始目录写入文件的深度。并且应该递归地为每个目录执行,在此过程中重置“文件计数器”和“目录计数器”。
我的脚本看起来像这样:

#!/bin/bash
#see executed comands when run
set -xeuo pipefail

rename() {
    # $1 - directory path, $2 - directory depth

    fileCounter=1
    dirCounter=1
    #enter a directory
    cd "$1"
    for file in *
    do
        if [[ -f "$file" ]]
        then
            #if its a regular file, write its depth and rename it
            echo "(I am file, my depth is $2)" > "$file"
            mv "$file" "file$fileCounter" 2>/dev/null
            #increase the counter
            (( fileCounter++ ))     
        elif [[ -d "$file" ]]
        then
            #its a directory - rename and call recursion
            mv "$file" "dir$dirCounter" 2>/dev/null
            #call recursion with depth + 1
            rename "dir$dirCounter" "(( $2 + 1 ))"
            #increase the counter
            (( dirCounter++ ))
        #else
            #do nothing, its not a regular file or a directory
        fi
    done

}

if [[ $# -gt 1 ]] 
then
    echo "Too many arguments >:(" 
    exit 1
fi

if [[ ! -d "$1" ]]
then
    echo "The directory doesn't exist"
    exit 1
fi
#start recursion
rename "$1" 0


然而,当我执行脚本时,它似乎在第一次递归调用后停止,所以我得到如下输出:

+ [[ 1 -gt 1 ]]
+ [[ ! -d testdir/ ]]
+ rename testdir/ 0
+ fileCounter=1
+ dirCounter=1
+ cd testdir/
+ for file in *
+ [[ -f jfjfjddsdsdsds ]]
+ echo '(I am file, my depth is 0)'
+ mv jfjfjddsdsdsds file1
+ ((  fileCounter++  ))
+ for file in *
+ [[ -f jfjfjfjf ]]
+ echo '(I am file, my depth is 0)'
+ mv jfjfjfjf file2
+ ((  fileCounter++  ))
+ for file in *
+ [[ -f kdskskk ]]
+ [[ -d kdskskk ]]
+ mv kdskskk dir1
+ rename dir1 '(( 0 + 1 ))'
+ fileCounter=1
+ dirCounter=1
+ cd dir1
+ for file in *
+ [[ -f * ]]
+ [[ -d * ]]
+ ((  dirCounter++  ))
+ for file in *
+ [[ -f kkkkkkkkk ]]
+ [[ -d kkkkkkkkk ]]
+ for file in *
+ [[ -f sadadasad ]]
+ [[ -d sadadasad ]]
+ for file in *
+ [[ -f skdjsjlsj ]]
+ [[ -d skdjsjlsj ]]


树看起来是这样的:

testdir/
├── dir1
├── file1
├── file2
├── kkkkkkkkk
├── sadadasad
│   ├── assd
│   ├── kakak
│   ├── ksja
│   ├── lklksl
│   └── lskal
└── skdjsjlsj
    ├── djfldjlfjd
    │   ├── eiuru
    │   ├── rhhrhshs
    │   ├── rhrhshs
    │   └── shhdshsd
    ├── jjskskk
    ├── kdjskdjfks
    ├── kjjrjjrj
    └── kjskjd


因此,脚本不会继续进行递归,甚至不会重命名最上层目录中的所有常规文件

我看不到脚本中的错误,为什么递归停止了?

vs3odd8k

vs3odd8k1#

为什么递归会停止?
因为在你下降cd "$1"之后,你不会从它出来。
一个简单的脏修复方法是在子shell中运行( rename "dir$dirCounter" "(( $2 + 1 ))" )。您可能还对pushdpopd感兴趣。或者,您可以将目录位置的当前深度作为另一个rename参数传递。我会选择最后一个选项,因为cd依赖于全局状态-当前目录-这就是为什么它会变得令人困惑。

相关问题