[英]Recursively list files from a given directory in Bash
I know that it can be done using ls -R path
. 我知道可以使用ls -R path
。 But I'm trying to learn the syntax and control structures of the shell language, so I'm trying to write my own code: 但我正在尝试学习shell语言的语法和控制结构,所以我正在尝试编写自己的代码:
#!/bin/sh
arg=$1;
lsRec() {
for x in $1*; do
if [ -d "$x" ]; then
lsRec $x;
else
echo "$x";
fi
done
}
lsRec $arg;
When I call the command ./ej2.sh ~/Documents/
, the terminal throws: segmentation fault (core dumped)
. 当我调用命令./ej2.sh ~/Documents/
,终端抛出: segmentation fault (core dumped)
。 Why I'm getting this error?, Am I missing something in my code? 为什么我收到此错误?我在代码中遗漏了什么?
Thanks. 谢谢。
Your algorithm is entering endless loop since lsRec
function implicitly expects its argument to end in "/". 您的算法进入无限循环,因为lsRec
函数隐式期望其参数以“/”结尾。 First level works, as you pass path ending with "/" as input, but second level doesn't, as the path you're making recursive call with doesn't end in "/". 第一级工作,因为您传递以“/”结尾的路径作为输入,但第二级不工作,因为您正在进行递归调用的路径不以“/”结尾。 What you could do is either add the slash when you make a recursive call, so it'll look like lsRec $x/
, or (better yet) add the slash in the loop arguments as in for x in $1/*; do
您可以做的是在进行递归调用时添加斜杠,所以它看起来像lsRec $x/
,或者(更好的是)在循环参数中添加斜杠,就像for x in $1/*; do
中for x in $1/*; do
for x in $1/*; do
(as system generally ignores multiple adjacent path separators). for x in $1/*; do
(因为系统通常忽略多个相邻的路径分隔符)。
Moving forward, I'd advise you to quote the values (eg for x in "$1/"*
, lsRec "$x"
, lsRec "$arg"
) to avoid issues when path contains whitespace characters. 继续前进,我建议你引用值(例如, for x in "$1/"*
, lsRec "$x"
, lsRec "$arg"
lsRec "$x"
),以避免路径包含空格字符时出现问题。 You'll get there when you create a directory with space in its name under directory hierarchy you're scanning. 当您在扫描目录层次结构下的名称中创建一个包含空格的目录时,您将到达那里。
The problem here is that "for x in $1*" finds $1, if that makes sense? 这里的问题是“for $ in $ 1 *”找到$ 1,如果这有意义的话? So it becomes an infinite loop. 所以它变成了无限循环。 There are two solutions: 有两种解决方案:
Because $1 is replaced by the argument passed to the function right? 因为$ 1被传递给函数的参数替换了吗? So if it sends "hello" then it becomes "for x in hello*". 因此,如果它发送“hello”,那么它就变成“for hello *”。 Now, that is a globbing pattern and will select "hello" and thus an infinite loop. 现在,这是一个通配模式,将选择“你好”,因此是一个无限循环。
The second solution works because "hello" becomes "hello/*" instead of "hello*". 第二个解决方案有效,因为“hello”变为“hello / *”而不是“hello *”。
This code works fine for me: 这段代码对我来说很好:
#!/bin/sh
arg=$1;
lsRec() {
for x in "$1"/*; do
echo "$x"
if [ -d "$x" ]; then
echo "This is a directory:"
lsRec "$x";
else
echo "This is not a directory:"
echo "$x";
fi
done
}
lsRec "$arg";
Hope it helps! 希望能帮助到你!
I think you created a fork bomb. 我想你创造了一个叉炸弹。 Your code creates an infinite recursion. 您的代码创建无限递归。
You should change the code to: 您应该将代码更改为:
#!/bin/sh
arg=$1;
lsRec() {
for x in $1/*; do
if [ -d "$x" ]; then
echo "$x" ## here you print the line
lsRec $x; ## here you pass the contents and NOT the line itself
## your programm was passing dirs without processing
## over and over
else
echo "$x";
fi
done
}
lsRec $arg;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.