Search code examples
bashscriptingcode-snippets

Bash Getting Access To Scripts In Subfolders Only While In Certain Directory


To elaborate,

Project Structure

current-working-directory
  -- scripts [d]
    -- script1 [d]
      -- script1 [f]
    -- script2 [d]
      -- script2 [f]
  -- README [f]
  -- executable [f]

Main Idea: I want to be able to run say function1 located in script1 as long as I am in current-working-directory or any subfolders.

I had multiple goes at this:

IDEA#1 .bashrc

function cd {
    builtin cd $@
    local dir
    if [ -d "bpm_modules" ]; then
      for dir in $(ls bpm_modules);do
        . "$PWD/bpm_modules/$dir/$dir"
      done
    fi
  }

wrapper around cd command

Caveat: since I source the files, once i leave the directory I still have access.


IDEA#2 .bashrc

function require {
    # You Have Gone Too Far
    [ "$1" == "$HOME" ] && return 1
    
    # Assign Parameters Accordingly
    [ $# -eq 1 ] && local CWD="$PWD" && local QUERY="$1"
    [ $# -eq 2 ] && local CWD="$1" && local QUERY="$2"
    local FOUND_MODULE=1

    # Error Handling
    function trapper {
        local BOO=$1
        local QUERY=$2
        NOT_FOUND="$(tput setaf 1)[DEPENDENCY]: $(tput sgr0)missing '$QUERY'"
        
        [[ $BOO -eq 1 ]] && echo "$NOT_FOUND"
    }
    
    # If In BCS Initialized Project
    if [ -d "$CWD/.bpm" ]; then
        
        # Check For Module
        for DIR in $( ls $CWD/bpm_modules); do
            [ "$DIR" == "$QUERY" ] && FOUND_MODULE=0 && source $CWD/bpm_modules/$DIR/$DIR
        done
        trap "trapper $FOUND_MODULE $QUERY" $?
    # Else Go Up A Directory Recursively
    else
        CWD_UP1=$(cd $CWD && cd .. && pwd)
        require $CWD_UP1 $QUERY
    fi

}

require would be used inside of say the executable from the project-directory graph above, followed by the script/folder name like so require script1, sourcing the file and allowing me to use functions inside executable


Repo @ Github

Package-Library

PS: I got 2 weeks of bash experience so..., id appreciate any recommandations or harsh truths.

PS1: 'bash puns amirite',this is used for a bash-package-manager im currently working on.


Solution

  • Let's say I am running a script called my_script.sh. If I want to implement your require function, that will source the script given in argument if that this script is located in a directory $my_dir, and crash otherwise, you can do:

    #!/bin/sh
    
    require() {
        if realpath --relative-to="$my_dir" "$1" | fgrep ../; then
            echo Script "$1" is not located in directory "$my_dir", exiting. >&2
            exit 1
        fi
        source $1
    }
    

    Please note that this would fail if a directory in the path returned by realpath ends with ... I think this is a reasonable limitation, but just so you know, in order to fix that, you could replace fgrep ../ by grep '\(^\.\./\)\|/\.\./'.