Выполнять bash-скрипты при входе в каталог

40

Как лучше всего выполнить скрипт при входе в каталог?
Когда я перехожу в новый каталог, я бы хотел, чтобы bash выполнял сценарий projectSettings.bash так же, как это делает RVM.

MageProspero
источник
2
В каждый каталог или выбранные? И тот же сценарий для каждого или нет?
энзотиб
Каждый каталог. Сценарий в каталоге с именем projectSettings.bash, если он существует.
MageProspero
Подобный вопрос о переполнении стека
Жиль "ТАК - перестань быть злым"

Ответы:

46

Вы можете создать cdфункцию (и popи pushd) и заставить ее обнаруживать, входите ли вы в этот конкретный каталог.

cd () { builtin cd "$@" && chpwd; }
pushd () { builtin pushd "$@" && chpwd; }
popd () { builtin popd "$@" && chpwd; }
unset_all_project_settings () {
  # do whatever it takes to undo the effect of projectSettings.bash,
  # e.g. unset variables, remove PATH elements, etc.
}
chpwd () {
  case $PWD in
    /some/directory|/some/other/directory) . ./projectSettings.bash;;
    *) unset_all_project_settings;;
  esac
}

Не делайте этого в каталогах, которые вы не включили в белый список, потому что вам будет очень легко обмануть вас при запуске произвольного кода - отправьте вам архив, чтобы вы распаковали его, перешли в созданный каталог и вы ' Теперь запустим код злоумышленника.

Я не рекомендую такой подход, потому что это означает, что скрипт будет выполнен, даже если вы войдете в этот каталог по какой-то причине, которая не связана с работой над проектом. Я предлагаю иметь определенную функцию, которая изменяет каталог проекта и использует сценарий настроек.

myproj () {
  cd /some/directory && . ./projectSettings.bash
}
Жиль "ТАК - перестань быть злым"
источник
1
Я начал в Ruby только недавно. Инструмент RVM полностью в Bash и один из лучших образцов магии Bash, которые я когда-либо видел. Я думаю, что ответ немного глупый, потому что одна из самых худших вещей, которые вы можете когда-либо сделать, это переехать что-то вроде этого, cdи, без сомнения, есть лучший способ. Даже использование $ PROMPT_COMMAND лучше!
MageProspero
3
Я был совершенно неправ и извиняюсь. RVM перегружал кд.
MageProspero
5
(из этой ветки комментариев удалены некоторые материалы про / анти-Ruby)
Michael Mrozek
1
в projectSettings.bash я предлагаю вам добавить переменную flag, чтобы не повторять инициализацию в случае выхода / повторного входа в каталог. Так что вложите все в if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. Это позволяет избежать проблем в случае, если вы делаете что-то вроде инициализации PATH = / mytools / bin: $ PATH.
паук
5
@spider Скорее всего, должен быть какой-то неустановленный механизм, если вы покинете каталог. Если вы выйдете и снова войдете, вы должны вернуть настройки!
Жиль "ТАК - перестань быть злым"
0

direnv может быть то, что вы ищете.

Вот пример, взятый из официальной документации:

$ cd ~/my_project
$ echo ${FOO-nope}
nope
$ echo export FOO=foo > .envrc
.envrc is not allowed
$ direnv allow .
direnv: reloading
direnv: loading .envrc
direnv export: +FOO
$ echo ${FOO-nope}
foo
$ cd ..
direnv: unloading
direnv export: ~PATH
$ echo ${FOO-nope}
nope
navigaid
источник