我尝试了以下这一行,从包含要循环浏览的文件夹的父文件夹开始:
for dir in */; do
cd $dir
for dir2 in */; do
cd $dir2
ls -d $PWD/*
cd ..
done
cd ..
done
但是它只输出我整个计算机的全部内容,然后返回到根文件夹/〜...对这种行为有任何解释吗?
bash
默认的“ globbing”(通配符匹配/扩展)行为是,如果通配符不匹配任何内容,则返回通配符表达式本身。因此,如果您cd
进入的目录中没有子目录,您最终将尝试cd
进入字面意义上的“ * /”(字面名称为星号的目录),该操作将失败,因此您将保留一个比您高的目录以为你会在循环中的这一点上。因此,当您到达时cd ..
,您将再次成为上一个目录。最终,您将退回到文件系统的根级别。
许多shell脚本编写者find(1)
在希望脚本遍历目录树时选择使用而不是shell循环。您的整个脚本片段将变为:
find . -type d
…或者,如果您确实想要绝对路径而不是相对路径:
find "$PWD" -type d
如果您要坚持使用shell循环,则可以尝试如下操作:
#!/bin/bash
set -evx
for dir in */; do
if [ -d "$dir" ]; then
cd "$dir"
for dir2 in */; do
if [ -d "$dir2" ]; then
cd "$dir2"
ls -d "$PWD"/*
cd ..
fi
done
cd ..
fi
done
请注意,我如何使用if
语句来测试的每个值dir
并dir2
确保它们是真正的目录,如果不是,则跳过它们。
还要注意这一set -evx
行,这是您初次编写/调试脚本时要设置的一组不错的选项:
-e
在出现第一个错误时停止。
-v
在执行前打印每一行。在执行所有各种替换/扩展之后,
-x
打印每一行。
如果您不喜欢默认通配符行为,当通配符表达式不匹配任何内容时返回通配符本身,那么还可以考虑在bash(1)
手册页中花一些时间查看诸如nullglob
和的shell选项failglob
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句