Bash получает доступ к скриптам во вложенных папках только в определенном каталоге

#bash #scripting #code-snippets

#bash #Сценарии #Фрагменты кода

Вопрос:

Для разработки,

Структура проекта

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

Основная идея: я хочу иметь возможность запускать, скажем, function1, расположенную в script1, до тех пор, пока
Я нахожусь в текущем рабочем каталоге или любых вложенных папках.

У меня было несколько попыток:

ИДЕЯ № 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
  }

  

обертка вокруг команды cd

Предостережение: поскольку я создаю исходные файлы, как только я покидаю каталог, у меня все еще есть доступ.


ИДЕЯ № 2 .bashrc

 function require {
    # You Have Gone Too Far
    [ "$1" == "$HOME" ] amp;amp; return 1
    
    # Assign Parameters Accordingly
    [ $# -eq 1 ] amp;amp; local CWD="$PWD" amp;amp; local QUERY="$1"
    [ $# -eq 2 ] amp;amp; local CWD="$1" amp;amp; 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 ]] amp;amp; 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" ] amp;amp; FOUND_MODULE=0 amp;amp; source $CWD/bpm_modules/$DIR/$DIR
        done
        trap "trapper $FOUND_MODULE $QUERY" $?
    # Else Go Up A Directory Recursively
    else
        CWD_UP1=$(cd $CWD amp;amp; cd .. amp;amp; pwd)
        require $CWD_UP1 $QUERY
    fi

}

  

require будет использоваться внутри, скажем executable , из приведенного выше графика project-directory, за которым следует имя сценария / папки, например, so require script1 , sourcing файл и позволяет мне использовать функции внутри executable


Репозиторий @ GitHub

Пакет-библиотека

PS: У меня 2 недели опыта работы с bash, так что …, я ценю любые рекомендации или суровые истины.

PS1: «bash каламбурирует amirite«, это используется для менеджера пакетов bash, над которым я сейчас работаю.

Комментарии:

1. Если вы используете абсолютный путь, вы сможете получить доступ из любого каталога `source / path/to /modules/bpm_modules/ $dir / $ dir»

2. @Noris: как вы правильно сказали, функция остается определенной, если вы выходите из своего текущего каталога. Вы могли бы сделать unset -f functionname , прежде чем покинуть каталог, но это означает, что вам нужно знать имена всех функций, которые вы хотите забыть. Это должны быть функции? Если вместо этого вы будете использовать скрипты bash и обращаться к ним только по относительному пути, вы автоматически сможете получить доступ только к «правильным».

3. @user1934428: насколько я понимаю, на данный момент, function — это правильный путь. я бы не хотел, чтобы скрипты запускались по требованию — (аналогично nodejs или npm, если хотите), это то, к чему я стремлюсь, поскольку для этого я никогда не узнаю все имена функций, которые я хочу «забыть»

4. Тогда это становится жестким. Вы могли бы, прежде чем искать файлы с новыми функциями, проанализировать выходные данные typeset -f , чтобы найти, какие функции определены прямо сейчас. После поиска файлов вы снова анализируете список функций. Из этого вы знаете, какие функции были добавлены, и вы можете выполнить соответствующие unset действия при возвращении.

5. @user1934428: это великолепно, я действительно не изучал set, unset и тому подобное. Какой позор. Спасибо, я перезвоню вам, как только попробую.

Ответ №1:

Допустим, я запускаю скрипт с именем my_script.sh . Если я хочу реализовать вашу функцию require, которая будет источником скрипта, указанного в аргументе, если этот скрипт находится в каталоге $my_dir , и сбой в противном случае, вы можете сделать:

 #!/bin/sh

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

Пожалуйста, обратите внимание, что это приведет к сбою, если каталог в пути, возвращаемый realpath оканчивается на .. . Я думаю, что это разумное ограничение, но, чтобы вы знали, чтобы исправить это, вы могли бы заменить fgrep ../ на grep '(^../)|/../' .

Комментарии:

1. Насколько я понимаю требования, это не решает проблему. OP не столько заинтересован в поиске сценариев для источника, он хочет «отменить» определения функций в этих сценариях, когда он покидает каталог.