Bash script to loop over all sub-directories, check existence of a script directory, and run a script there

I’m new to bash scripting and I’m trying to make a script which uses a for loop to find all the folders in the directory where it is started, and then use an if statement to find another folder within them which has a name templates, in which I then want to run a python command to execute python scripts stored in that folder.

  • My directory structure looks like this:
    all/
        this_script.sh
        one/
            templates/
                      render_j2.py
        two/
            templates/
                      render_j2.py
    
  • What I’ve tried for this_script-sh is
    for file in *; do
      if [[ "$file"==*"templates"* ]];
      then
        cd $file
      fi
    done
    

    and also tried this:

    for file in *; do
    find . templates
    python render_j2.py; 
    done
    

My main issue is that I can’t enter the templates folder, and even when I can, the python command cant find the python files to run.

Asked By: frank peters

||

This is kind of a non-answer but this seems like an over complicated setup. If you have an unstated reason you must or just want (to learn perhaps) the loop then this isn’t going to be your answer but…You can do this sans loop with the find command.

Something like

find $HOME/my/folders -type d -name templates -exec my.py {} ;
Answered By: g0Brrrr

Since you are already using find, why not offload the entire task to it? You could try the following:

find . -type f -path "*/templates/render_j2.py" -execdir python render_j2.py ;

This will search for all files render_j2.py in a directory templates below your starting point, and in the directory where the file was found, execute your python command.

Answered By: AdminBee

There’s a number of things wrong with this:

  • Neither version is testing if $file is a directory
  • When the first version uses cd $file then $file will not be a valid path in the next iteration of the loop, because you changed directories; putting cd in a subshell (using parentheses) along with things you want to do in that directory would fix this.
  • In the second version, the find syntax is wrong to do what you want
  • it doesn’t make sense to run find in a loop like this, find does its own loop internally

Something like this might work:

find . -name templates -type d -execdir python {}/render_j2.py ;

This would be equivalent to

(cd all/one && python ./templates/render_j2.py )
(cd all/two && python ./templates/render_j2.py )
...

which still might not be exactly what you want.

Answered By: user10489
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.