bash while声明

时间:2012-01-11 14:42:47

标签: bash while-loop pipe

我有两个不同的脚本基本相同:计算当前目录中的子目录:

c=0

ls -l | grep "^d" | while read zeile
do
    c=`expr $c + 1`
    echo $c
done

echo "Subdirs: $c"

c=0

while read zeile
do
    c=`expr $c + 1`
    echo $c
done < <(ls -l | grep "^d")

echo "Subdirs: $c"

我的问题是,在第一个版本中,“c”似乎在while循环结束后失去了它的值。

输出

1)

1
2
3
Subdirs: 0

2)

1
2
3
Subdirs: 3

你们有人可以向我解释,为什么会这样?

提前致谢 亚历

3 个答案:

答案 0 :(得分:3)

在第一种情况下,对c的赋值发生在|之后,即在子shell中。您不能从子shell更改父shell中的变量。 顺便说一句,为什么不使用let c++代替反引号和expr?

答案 1 :(得分:1)

如果我必须计算子目录,那么我将使用这两个命令中的任何一个:

find . -regex ".\{2,\}" -maxdepth 1 -type d | wc -l
ls -l | grep "^d" | wc -l

答案 2 :(得分:0)

should not use ls in that way

你应该使用for循环和glob来迭代文件或目录。

for f in *
do
    if [[ -d $f ]]
    then
        (( c++ ))
    fi
done
echo "Subdirs: $c"

for f in */
do
    (( c++ ))
done
echo "Subdirs: $c"

这是一种hackish方式:

arr=(*/); echo "Subdirs: ${#arr[@]}"

您可能希望将nullglobdotglob用于上述任何一种情况。有关详细信息,请参阅BashFAQ/004

Choroba对于子shell问题是正确的。