Search code examples
bashfunctionsdkman

'source' statement and 'function' declaration at end of .bashrc interfere with one another


At first I created a script to 'find' a file and switch to that directory. Alas, upon returning from the script, the 'cd' was unchanged. Directory changes within a script are local to that script. I forgot. Sue me.

So... I created that same code as a function in the middle of .bashrc. When I re-enter the Bash shell, the function is not defined or visible. So... I placed the function at the end of .bashrc and -- voila! -- it worked. Here is the function:

function goto {

    if [[ "$1" == "" ]]
    then
        echo "[ERROR] $0 requires a filename as input."
        echo "[INFO]  Usage: $0 <filename> finds file and changes to that directory."
    else
        echo "[INFO] Looking for file: $1"
        declare -x -a full_filepath=$(find . -name "$1")
        if [[ "${full_filepath[0]}" == "" ]]
        then
            echo "[ERROR] Unable to find requested file $1. Exiting..."
        else
            local filepath=${full_filepath[0]%/*}
            local filename=${full_filepath[0]##*/}
            echo "[INFO] Switching to $filepath to locate $filename..."
            cd $filepath
        fi
    fi
}

Now here's the problem. I had to move it after SDKMan's init code in .bashrc (ignoring the warning that #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!). Not surprisingly, 'sdk' no longer works.

Is there a "right way" to include a function in .bashrc so that other scripts like SDKMan's can remain at the end, for whatever-in-gods-name reason it must be there...???


Solution

  • I uninstalled then reinstalled SDKMan and the functions are now working as is SDKMan.

    The conditional they add is odd. It reminds me of the shortcuts in Perl.

    Here is the code added to .bashrc:

    #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!
    export SDKMAN_DIR="/home/peter/.sdkman"
    [[ -s "/home/peter/.sdkman/bin/sdkman-init.sh ]] && source "/home/peter/.sdkman/bin/sdkman-init.sh
    

    This works just as well:

    if [[ -s "/home/peter/.sdkman/bin/sdkman-init-sh" ]]; then source "/home/peter/.sdkman/bin/sdkman-init-sh"; fi
    

    but it's a few characters longer, I guess. And if they had used the var they just defined above it, it would be even shorter:

    if [[ -s "$SDKMAN_DIR/bin/sdkman-init-sh" ]]; then source "$SDKMAN_DIR/bin/sdkman-init-sh"; fi
    

    Barmar: You were right. Location in .bashrc doesn't matter. Thanks. Wiimm: Thanks for the tip. Mark: For good measure, I've exported the functions. Thanks.