Ejecute scripts de bash al ingresar a un directorio

40

¿Cuál es la mejor manera de ejecutar un script al ingresar a un directorio?
Cuando me muevo a un nuevo directorio, me gustaría que bash ejecute el script projectSettings.bash al igual que RVM.

MagoProspero
fuente
2
¿En cada directorio o en los seleccionados? ¿Y el mismo guión para cada uno, o no?
enzotib
Cada directorio El script en el directorio llamado projectSettings.bash si existe.
MageProspero
Pregunta similar sobre Stack Overflow
Gilles 'SO- deja de ser malvado'

Respuestas:

46

Usted puede hacer cduna función (y pop, y pushd), y hacer que detecta si se introduce ese directorio en particular.

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
}

No haga esto en directorios que no haya incluido en la lista blanca, ya que facilitaría que alguien lo engañe para que ejecute código arbitrario: le enviará un archivo, así que descomprímalo, cámbielo al directorio que creó, y usted ' Ahora he ejecutado el código del atacante.

No recomiendo este enfoque, porque significa que el script se ejecutará incluso si ingresa a ese directorio por alguna razón que no está relacionada con el trabajo en el proyecto. Sugiero tener una función específica que cambie al directorio del proyecto y obtenga el script de configuración.

myproj () {
  cd /some/directory && . ./projectSettings.bash
}
Gilles 'SO- deja de ser malvado'
fuente
1
Empecé en Ruby hace un rato. La herramienta RVM está completamente en Bash y una de las mejores piezas de magia de Bash que he visto. Creo que la respuesta es un poco tonta porque una de las cosas absolutamente peores que puedes hacer es sobrepasar algo como cdy sin duda hay una mejor manera. ¡Incluso usar $ PROMPT_COMMAND es mejor!
MageProspero
3
Estaba completamente equivocado y me disculpo. RVM estaba sobrecargando cd.
MageProspero
55
(eliminado algunas cosas tangenciales pro / anti-Ruby de este hilo de comentarios)
Michael Mrozek
1
en projectSettings.bash le sugiero que agregue una variable de marca para no repetir la inicialización en caso de que salga / vuelva a ingresar al directorio. Así que encierra todo if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. Esto es para evitar problemas en caso de que haga algo PATH = / mytools / bin: $ PATH tipo de inicialización.
araña
55
@spider Por el contrario, debería haber algún tipo de mecanismo no establecido si abandona el directorio. Si sale y vuelve a entrar, ¡debería recuperar la configuración!
Gilles 'SO- deja de ser malvado'
0

Direnv podría ser lo que estás buscando.

Aquí hay un ejemplo tomado de la documentación 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
fuente