Search code examples
linuxbashfor-loopgitlab-ci

Execute multiple commands against a specific file if found in a directory recusively


I have 2 directories paul & matt with some subfolders within each which potentially contains (or will contain) a kustomization.yaml file. What I am trying to do is to run multiple commands in the path where a kustomization.yaml is found in paul/* and matt/*. So if I was to do this manually:

cd paul
somecommand1 kustomization.yaml
somecommand2 kustomization.yaml
cd paul/test
somecommand1 kustomization.yaml
somecommand2 kustomization.yaml
cd paul/test/test1
somecommand1 kustomization.yaml
somecommand2 kustomization.yaml
---
cd matt
somecommand1 kustomization.yaml
somecommand2 kustomization.yaml
cd matt/test
somecommand1 kustomization.yaml
somecommand2 kustomization.yaml
cd matt/test/test1
somecommand1 kustomization.yaml
somecommand2 kustomization.yaml

I am still learning bash but I know that a Bash script I can call on my GitLab pipeline with some steps that will do something like a loop to find any kustomization.yaml in those 2 directories recursively, then run x, y, and z against any found kustomization.yaml file will do the job.


Solution

  • You could use find command with multiple use of -exec option like that:

    find matt paul -name "kustomization.yaml" \
      -exec echo -n "Work on '{}' file in " \; -exec pwd \; \
      -exec somecommand1 {} \; \
      -exec somecommand2 {} \;
    

    Alternative

    Use -execdir option to execute commands in the directory where file found.

    find matt paul -name "kustomization.yaml" \
      -execdir echo -n "Work on '{}' file in: " \; -execdir pwd \; \
      -execdir somecommand1 {} \; \
      -execdir somecommand2 {} \;
    

    Alternative 2

    Use a subscript: /some/path/my_commands.sh

    #! /usr/bin/env bash
    
    # cd "${1%/*}" # Necessary if you use `-exec` option instead of `-execdir`
    echo "Work on '$1' in '$(pwd)' dirrectory"
    somecommand1 "$1"
    somecommand1 "$1"
    
    chmod +x /some/path/my_commands.sh
    

    And use only one -execdir option:

    find matt paul -name "kustomization.yaml" \
      -execdir /some/path/my_commands.sh {} \;
    

    This alternative is very useful if you want to make treatments with return codes from somecommand* executions:

    Subscript: /some/path/my_commands.sh

    #! /usr/bin/env bash
    
    # cd "${1%/*}" # Necessary if you use `-exec` option instead of `-execdir`
    # It may be important to check the return code of `cd` command before continue
    # if [[ $? -ne 0 ]]; then
    #   echo "ERR: ${0##*/}: Cannot change directory to '${1%/*}'" >&2
    #   exit 1
    # fi
    
    echo "Work on '$1' file in '$(pwd)' directory"
    
    if somecommand1 "$1"; then
      ...
    else
      ...
    fi
    ...
    if somecommand2 "$1"; then
      ...
    else
      ...
    fi