Eseguire script bash quando si accede a una directory


40

Qual è il modo migliore per eseguire uno script quando si accede a una directory?
Quando mi sposto in una nuova directory, vorrei che bash eseguisse lo script projectSettings.bash proprio come fa RVM.


2
In ogni directory o in quelle selezionate? E lo stesso copione per ognuno o no?
enzotib,

Ogni directory. Lo script nella directory denominata projectSettings.bash se esiste.
MageProspero,

Risposte:


46

È possibile creare cduna funzione (e pope pushd) e farlo rilevare se si immette quella directory specifica.

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
}

Non farlo nelle directory che non hai inserito nella whitelist, perché sarebbe molto facile per qualcuno indurti a eseguire codice arbitrario: invia un archivio, quindi decomprimilo, cambia nella directory che ha creato e tu ' ora eseguo il codice dell'attaccante.

Non consiglio questo approccio, perché significa che lo script verrà eseguito anche se si immette quella directory per qualche motivo non correlato al lavoro sul progetto. Suggerisco di avere una funzione specifica che cambia nella directory del progetto e genera lo script delle impostazioni.

myproj () {
  cd /some/directory && . ./projectSettings.bash
}

1
Ho iniziato a Ruby solo un po 'di tempo fa. Lo strumento RVM è completamente in Bash e uno dei migliori pezzi di magia di Bash che abbia mai visto. Penso che la risposta sia un po 'sciocca perché una delle cose assolutamente peggiori che puoi mai fare è cavalcare qualcosa del genere cde senza dubbio c'è un modo migliore. Anche usare $ PROMPT_COMMAND è meglio!
MageProspero,

3
Ho sbagliato completamente e mi scuso. RVM stava sovraccaricando cd.
MageProspero,

5
(rimosso alcune cose tangenziali pro / anti-Ruby da questo thread di commenti)
Michael Mrozek

1
in projectSettings.bash ti suggerisco di aggiungere una variabile flag per non ripetere l'inizializzazione in caso di uscita / re-accesso alla directory. Quindi racchiudi tutto dentro if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. Questo per evitare problemi nel caso in cui si faccia qualcosa PATH = / mytools / bin: $ PATH tipo di inizializzazione.
ragno,

5
@spider Piuttosto ci dovrebbe essere una sorta di meccanismo non impostato se si lascia la directory. Se esci e rientri, dovresti ripristinare le impostazioni!
Gilles 'SO- smetti di essere malvagio' il

0

direnv potrebbe essere quello che stai cercando.

Ecco un esempio tratto dalla documentazione ufficiale:

$ 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.