Executar scripts bash ao inserir um diretório

40

Qual é a melhor maneira de executar um script ao entrar em um diretório?
Quando mudo para um novo diretório, gostaria que o bash execute o script projectSettings.bash, da mesma forma que o RVM.

MageProspero
fonte
2
Em todos os diretórios, ou selecionados? E o mesmo script para cada um, ou não?
enzotib 24/09/11
Todo diretório. O script no diretório chamado projectSettings.bash, se existir.
MageProspero
Pergunta semelhante sobre Stack Overflow
Gilles 'SO- stop be evil'

Respostas:

46

Você pode criar cduma função (e pope pushd) e detectá-la se inserir esse diretório específico.

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
}

Não faça isso em diretórios que você não incluiu na lista de permissões, porque seria muito fácil para alguém induzi-lo a executar código arbitrário - envie um arquivo para você, descompacte-o, mude para o diretório que ele criou e você ' Agora, execute o código do invasor.

Eu não recomendo essa abordagem, porque significa que o script será executado mesmo se você entrar nesse diretório por algum motivo não relacionado ao trabalho no projeto. Sugiro ter uma função específica que mude para o diretório do projeto e origine o script de configurações.

myproj () {
  cd /some/directory && . ./projectSettings.bash
}
Gilles 'SO- parar de ser mau'
fonte
11
Eu só comecei em Ruby há pouco tempo. A ferramenta RVM está completamente no Bash e é uma das melhores peças de magia do Bash que eu já vi. Eu acho que a resposta é um pouco boba, porque uma das coisas absolutamente piores que você pode fazer é andar sobre algo como cde existe, sem dúvida, uma maneira melhor. Mesmo usando $ PROMPT_COMMAND é melhor!
MageProspero #
3
Eu estava completamente errado e peço desculpas. O RVM estava sobrecarregando o CD.
MageProspero
5
(removeu algumas coisas tangenciais pró / anti-Ruby deste tópico)
Michael Mrozek
11
no projectSettings.bash, sugiro que você adicione uma variável de flag para não repetir a inicialização, caso saia / digite novamente o diretório. Portanto, inclua tudo if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. Isso é para evitar problemas, caso você faça algo do tipo PATH = / mytools / bin: $ PATH de inicialização.
spider
5
@spider Em vez disso, deve haver algum tipo de mecanismo não definido, se você deixar o diretório. Se você sair e entrar novamente, recupere as configurações!
Gilles 'SO- stop be evil'
0

direnv pode ser o que você está procurando.

Aqui está um exemplo retirado da documentação oficial:

$ 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
fonte