I am trying to create a shell script similar to ls, but which only lists directories. I have the first half working (no argument version), but trying to make it accept an argument, I am failing. My logic is sound I think, but I'm missing something on the syntax, I'm guessing in the bolded line? Any help would be greatly appreciated, thanks!
if [ $# -eq 0 ] ; then
d=`pwd`
for i in * ; do
if test -d $d/$i ; then
echo "$i:"
fi
done
else
if [ $# -eq 1 ] ; then
d=$1
for i in * ; do
if test -d $d/$i ; then
echo "$i:"
fi
done
fi
fi
No, the goal is to check if the contents (of the argument directory) are directories or not. I got it working with this code below, but what I don't understand is why the for/if notation I used in the top (no argument version) had to be changed so much for the bottom (argument version). I guess I'm not sure exactly what "i in *" (in the top version) is iterating over. How does it define *?
if [ $# -eq 0 ] ; then
d=`pwd`
for i in * ; do
if test -d "$d"/"$i" ; then
echo "$i:"
fi
done
else
if [ $# -eq 1 ] ; then
d="$1"
for i in "$d"/* ; do
if test -d "$i" ; then
echo "${i##*/}:"
fi
done
fi
fi
The problem in your script is that you are not switching to the directory passed in on the command line. You are examining all files in the current directory but prepending the parameter.
From your script:
else
if [ $# -eq 1 ] ; then
d=$1
for i in * ; do #this lists all files in the current directory
if test -d $d/$i ; then #$d/$i might not exist because $i is in the pwd and may not be in $d
echo "$i:"
fi
done
fi
fi
Easiest solution, is to cd to the desired directory and then run your loop, leaving the $d/ out of the test. And don't forget to test that the directory switch worked and issuing an error if it doesn't --- there's nothing to prevent the user from putting a regular file on the command line.
Since this seems like an assignment, I'm not offering any code.
---------- Post updated at 23:24 ---------- Previous update was at 23:22 ----------
Looks like a few of us crossed posts. Glad you figured it out, and you should have some meaningful explanation now too.
Yes, the explanation given in your post and the one above were what I needed.
+thanks to all that helped!
---------- Post updated at 10:50 PM ---------- Previous update was at 09:31 PM ----------
You're right, it is an assignment, but I'm actually more interested in learning than in "just" getting it done. Even though I had it working with the code I posted earlier in post #7 (changing "for i in " to "for i in $d/"), I still am trying to find the most efficient way to do it.
Which is why I appreciate your alternate suggestion above of cd'ing before looping. Funny thing is that I had that thought myself hours before frustration led me to post here... but for whatever reason I didn't try to implement it, or didn't think it would work. But now that you've suggested it, it reminded me I had it, so I tried it out. It is literally as easy as taking the top loop and adding 2 extra lines ("cd $1" before the loop and "cd -" after it). Grr... a 5-second solution that I couldn't find earlier after two hours racking my brains. Oh well, at least I got it working two different ways now. Thanks again!
EDIT: and you're right I should add a conditional to check it is actually a directory... will get on that soon too!
if [ $# -eq 0 ] ; then
d=`pwd`
for i in * ; do
if test -d "$d"/"$i" ; then
echo "$i:"
fi
done
else
if [ $# -eq 1 ] ; then
cd $1
d=`pwd`
for i in * ; do
if test -d "$d"/"$i" ; then
echo "$i:"
fi
done
cd -
fi
fi