#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
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 не столько заинтересован в поиске сценариев для источника, он хочет «отменить» определения функций в этих сценариях, когда он покидает каталог.