cd into all directories, execute command on files in that directory, and return to previous current directory

I’m attempting to write a script that will be run in a given directory with many single level sub directories. The script will cd into each of the sub directories, execute a command on the files in the directory, and cd out to continue onto the next directory. What is the best way to do this?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

for d in ./*/ ; do (cd "$d" && somecommand); done

Method 2

The best way is to not use cd at all:

find some/dir -type f -execdir somecommand {} ;

execdir is like exec, but the working directory is different:

-execdir command {} [;|+]
  Like   -exec,   but  the  specified  command  is  run  from  the
  subdirectory containing the matched file, which is not  normally
  the  directory  in  which  you  started  find.  This a much more
  secure  method  for  invoking  commands,  as  it   avoids   race
  conditions  during resolution of the paths to the matched files.

It is not POSIX.

Method 3

for D in ./*; do
    if [ -d "$D" ]; then
        cd "$D"
        run_something
        cd ..
    fi
done

Method 4

cd -P .
for dir in ./*/
do cd -P "$dir" ||continue
   printf %s\n "$PWD" >&2
   command && cd "$OLDPWD" || 
! break; done || ! cd - >&2

The above command doesn’t need to do any subshells – it just tracks its progress in the current shell by alternating $OLDPWD and $PWD. When you cd - the shell exchanges the value of these two variables, basically, as it changes directories. It also prints the name for each directory as it works there to stderr.

I just had a second look at it and decided I could do a better job with error handling. It will skip a dir into which it cannot cd – and cd will print a message about why to stderr – and it will break w/ a non-zero exit code if your command does not execute successfully or if running command somehow affects its ability to return to your original directory – $OLDPWD. In that case it also does a cd - last – and writes the resulting current working directory name to stderr.

Method 5

Method 1 :

for i in `ls -d ./*/`
do
  cd "$i"
  command
  cd ..
done

Method 2 :

for i in ./*/
do
  cd "$i"
  command
  cd..
done

Method 3 :

for i in `ls -d ./*/`
do
  (cd "$i" && command)
done

I hope this was useful. You can try all permutation and combinations on this.

Thanks 🙂


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x