Reputation: 1514
I know that it can be done using 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:
#!/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)
. Why I'm getting this error?, Am I missing something in my code?
Thanks.
Upvotes: 6
Views: 3615
Reputation: 88
The problem here is that "for x in $1*" finds $1, if that makes sense? So it becomes an infinite loop. There are two solutions:
Because $1 is replaced by the argument passed to the function right? So if it sends "hello" then it becomes "for x in 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*".
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!
Upvotes: 5
Reputation: 350
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;
Upvotes: 2
Reputation: 3049
Your algorithm is entering endless loop since lsRec
function implicitly expects its argument to end in "/". 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
(as system generally ignores multiple adjacent path separators).
Moving forward, I'd advise you to quote the values (e.g. for x in "$1/"*
, lsRec "$x"
, lsRec "$arg"
) to avoid issues when path contains whitespace characters. You'll get there when you create a directory with space in its name under directory hierarchy you're scanning.
Upvotes: 8