Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want to do some task in every directory in current path so I tried

for DIRECTORY in `find . -type d -maxdepth 1`
do
    cd $DIRECTORY

    #DO STUFF

    cd ..
done

but I got a long error of no such file.

updateall.sh: line 5: cd: ./abc No such file or directory

Why ? I tried cd ./abc and it was fine.

thanks

share|improve this question
1  
Also, don't do cd .. but rather cd -. Instead of taking you up a level, cd - takes you back to the previous directory, no matter where that was. Also, if you use ( cd $DIRECTORY; do-stuff; ) you don't need to use a final cd at all as the current directory gets restored when you return from the ( ... ). –  Mei Jan 11 '12 at 20:06
    
Thanks for the tips. Actually when I used ubuntu I always use pop/push $DIRECTORY in script. –  yumyai Jan 13 '12 at 2:47
    
I think you meant pushd and popd - and they don't work in ksh (or other non-bash shells) as far as I know. Those commands are handy though - when I used to use csh I used them a bit. –  Mei Jan 13 '12 at 17:24
add comment

2 Answers

up vote 3 down vote accepted

You need to add -mindepth 1. Otherwise you cd .. out from the original base directory in the first loop repetition and end up in its parent directory.

Easy to notice when you dry-run the find expression:

$ find . -type d -maxdepth 1
.
./abc

In the first loop, you cd ., which does nothing, and then cd .., from which you're unable to enter all the other directories you found.


If it's no problem with spaces in directory names, you can always find $PWD instead of find . to use absolute paths, or store the original $PWD in a variable you can cd to ($OLDPWD and cd - likely won't work though), instead of cd ...

share|improve this answer
    
wow stupid me. Answer is right there before my eyes and I still miss it. Thanks for the tip too. –  yumyai Jan 11 '12 at 7:55
add comment

You might consider using -execdir, if you're using gnu-find. It's similar to -exec, but will execute the command from the directory. (It might be an ad hoc script, if it would fill multiple lines for example.)

find . -type d -maxdepth 1 -mindepth 1 -execdir dostuff ";" 

Using

for DIRECTORY in `find ...`

is vulnerable to blanks and similar stuff in directory names.

Example:

mkdir "a a"
echo "123" > a 

for f in $(find . -mindepth 1 -type d); do echo "using $f"; ls -l $f ; done 
using ./a
-rw-r--r-- 1 stefan stefan 4 2012-01-13 08:15 ./a
using a
-rw-r--r-- 1 stefan stefan 4 2012-01-13 08:15 a
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.