Führen Sie Bash-Skripte aus, wenn Sie ein Verzeichnis eingeben

40

Was ist der beste Weg, um ein Skript auszuführen, wenn Sie in ein Verzeichnis eintreten?
Wenn ich in ein neues Verzeichnis wechsle, möchte ich, dass Bash das Skript projectSettings.bash ausführt, ähnlich wie RVM.

MageProspero
quelle
2
In jedes Verzeichnis oder in ausgewählte? Und das gleiche Skript für jeden, oder nicht?
Enzotib
Jedes Verzeichnis. Das Skript im Verzeichnis projectSettings.bash, falls vorhanden.
MageProspero
Ähnliche Frage zu Stack Overflow
Gilles 'SO - hör auf böse zu sein'

Antworten:

46

Sie können cdeine Funktion (und popund pushd) erstellen und erkennen lassen, ob Sie dieses bestimmte Verzeichnis betreten.

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
}

Tun Sie dies nicht in Verzeichnissen, die Sie nicht auf die Whitelist gesetzt haben, da es für jemanden sehr einfach wäre, Sie zum Ausführen von beliebigem Code zu verleiten. Senden Sie ein Archiv, entpacken Sie es, wechseln Sie in das erstellte Verzeichnis und Führen Sie jetzt den Code des Angreifers aus.

Ich empfehle diesen Ansatz nicht, da er bedeutet, dass das Skript ausgeführt wird, selbst wenn Sie dieses Verzeichnis aus einem Grund eingeben, der nichts mit der Arbeit am Projekt zu tun hat. Ich schlage vor, über eine bestimmte Funktion zu verfügen, die sich im Projektverzeichnis ändert und das Einstellungsskript als Quelle verwendet.

myproj () {
  cd /some/directory && . ./projectSettings.bash
}
Gilles 'SO - hör auf böse zu sein'
quelle
1
Ich habe erst vor einiger Zeit in Ruby angefangen. Das RVM-Tool ist komplett in Bash und eines der besten Stücke der Bash-Magie, die ich je gesehen habe. Ich denke, die Antwort ist ein bisschen albern, denn eines der absolut schlimmsten Dinge, die Sie jemals tun können, ist, etwas wie Over Ride zu machen, cdund es gibt ohne Zweifel einen besseren Weg. Sogar mit $ PROMPT_COMMAND ist besser!
MageProspero
3
Ich habe mich völlig geirrt und entschuldige mich. RVM hat die CD überladen.
MageProspero
5
(Tangentiales Pro / Anti-Ruby-Material aus diesem Kommentarthread entfernt)
Michael Mrozek
1
In der Datei projectSettings.bash empfehle ich Ihnen, eine Flag-Variable hinzuzufügen, um die Initialisierung nicht zu wiederholen, falls Sie das Verzeichnis verlassen oder erneut betreten. Also alles einschließen in if [ -z $MYSETTINGS ] ; then export MYSETTINGS=1 ; echo your settings here ; fi. Dies dient zur Vermeidung von Problemen, falls Sie eine Initialisierung mit PATH = / mytools / bin: $ PATH durchführen.
Spinne
5
@spider Vielmehr sollte es eine Art nicht gesetzten Mechanismus geben, wenn Sie das Verzeichnis verlassen. Wenn Sie den Raum verlassen und erneut betreten, sollten Sie die Einstellungen wiederherstellen!
Gilles 'SO- hör auf böse zu sein'
0

direnv könnte das sein, wonach du suchst.

Hier ist ein Beispiel aus der offiziellen Dokumentation:

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