Doing something in a directory, a simple bash line

If you are recoding large directories of files, or creating directory indexes, you may need a script that runs another script in a directory. The easiest way to do this is probably using something like the bash for loop:

for dir in *; do
  cd "$dir"
  indexThisDirectory
  cd -
done;

Although you may think this should work, it has a small problem: if the directory does not exist, the first cd will fail and cd - will bring you back to the last dir you did. After entering that directory, the next directory will fail and bring you even more back into time etc.

A solution may be the following:

for dir in *; do
  cd "$dir" && (indexThisDirectory ; cd - )
done;

Which makes sure to only cd - when you enter the directory correctly. But now we go a step further and run into something else. How do we combine this with xargs? The obvious solution:

find ./ -type d -print0 |xargs -0 -n1 -IDIR cd "DIR" && (indexThisDirectory ; cd - )

won't work correctly: the && will become part of the a new command as bash interprets it as the end of the xargs command and a conditional.

Tired of hacking together and to stupid to find the good obvious solution, I decided to write a little bash script which entails the last part of the previous xargs command and save it as inDirDo:

#!/bin/bash
PARS=("$@")
cd "${PARS[0]}" && ( unset PARS[0]; ${PARS[@]} ; cd -)

Saving that and making it executable (and putting it in your PATH) will allow you to do something like this:

find ./ -type d -mindepth 2 -print0|xargs -n1 -0 -I HERE inDirDo "HERE" indexdirectorycommand and parameters

Another job well automated with the power of GNU.