Shell脚本:函数中的变量范围

时间:2013-08-28 20:59:15

标签: function shell scope

我编写了一个快速shell脚本来模拟xkcd #981的情况(没有硬链接,只是父目录的符号链接),并使用递归函数来创建所有目录。不幸的是,这个脚本没有提供所需的结果,所以我认为我对变量$ count范围的理解是错误的。

如何才能正确地使用递归来创建20个级别的文件夹,每个文件夹包含3个文件夹(3 ^ 20个文件夹,以软链接结尾回到顶部)?

#!/bin/bash
echo "Generating folders:"
toplevel=$PWD
count=1
GEN_DIRS() {
for i in 1 2 3
do
        dirname=$RANDOM
        mkdir $dirname
        cd $dirname
        count=$(expr $count + 1)
        if [ $count < 20 ] ; then
                GEN_DIRS
        else
                ln -s $toplevel "./$dirname"
        fi
done
}
GEN_DIRS
exit

2 个答案:

答案 0 :(得分:1)

试试这个(脚本的修改版本) - 它似乎对我有用。不过,我拒绝测试到20级深度;在8级深度,三个顶级目录中的每一个在Mac文件系统上占用大约50 MB。

#!/bin/bash
echo "Generating folders:"
toplevel=$PWD
GEN_DIRS()
{
    cur=${1:?}
    max=${2:?}
    for i in 1 2 3
    do
        dirname=$RANDOM
        if [ $cur -le $max ]
        then
            (
            echo "Directory: $PWD/$dirname"
            mkdir $dirname
            cd $dirname
            GEN_DIRS $((cur+1)) $max
            )
        else
            echo "Symlink:   $PWD/$dirname"
            ln -s $toplevel "./$dirname"
        fi
    done
}

GEN_DIRS 1 ${1:-4}

第6行和第7行给出了传递给函数的位置参数($1$2)的名称 - ${1:?}表示法只是表示如果省略传递参数{ {1}},您从shell(或子shell)收到错误消息并退出。

括号本身(上面的第13行和第18行)表示中间的命令是在子shell中运行的,因此子shell中目录的更改不会影响父shell。

第11行的条件现在使用算术($1)而不是字符串-le比较;这对于深度嵌套更有效(因为<是字典比较,因此级别9不低于级别10)。这也意味着<命令可以使用而不是[命令(尽管[[也可以使用,我更喜欢老式的符号)。

答案 1 :(得分:0)

我最终创建了一个这样的脚本:

#!/bin/bash

echo "Generating folders:"

toplevel=$PWD

level=0
maxlevel=4

function generate_dirs {
    pushd "$1" >/dev/null || return
    (( ++level ))
    for i in 1 2 3; do
        dirname=$RANDOM
        if (( level < maxlevel )); then
            echo "$PWD/$dirname"
            mkdir "$dirname" && generate_dirs "$dirname"
        else
            echo "$PWD/$dirname (link to top)"
            ln -sf "$toplevel" "$dirname"
        fi
    done
    popd >/dev/null 
    (( --level ))
}

generate_dirs .

exit