Frage

Glauben Sie, Ändern Verzeichnisse innerhalb bash oder Perl-Skripte ist akzeptabel? Oder sollte man auf jeden Fall tun, dies vermeiden?

Was ist die beste Praxis für dieses Problem?

War es hilfreich?

Lösung

Das aktuelle Arbeitsverzeichnis ist lokal auf das Ausführen der Schale, so dass Sie den Benutzer nicht beeinflussen können, es wäre denn er ist „Punktierung“ (es ist in dem aktuell Shell ausgeführt wird, im Gegensatz zu laufen sie normalerweise einen neuen Shell-Prozess erstellen) Ihr Skript .

Eine sehr gute Möglichkeit, dies zu tun, ist Subshells zu verwenden, die ich oft in Aliase tun.

alias build-product1='(cd $working-copy/delivery; mvn package;)'

Die geklam- mert wird sicherstellen, dass der Befehl von einer Unterschale ausgeführt wird, und somit wird das Arbeitsverzeichnis meiner Schale nicht beeinflussen. Auch wird es keinen Einfluss auf das Last-Arbeitsverzeichnis, so cd -;. wie erwartet funktioniert

Andere Tipps

Wie Hugo sagte, können Sie nicht beeinflussen Ihre Eltern Prozess cwd so ist es kein Problem.

Wenn die Frage mehr anwendbar ist, wenn Sie nicht den gesamten Prozess steuern können, wie in einem Unterprogramm oder Modul. In diesen Fällen sollten Sie das Unterprogramm in demselben Verzeichnis verlassen, wie Sie eingegeben haben, sonst feine Aktion-at-a-Abstand kriecht, in dem verursacht Fehler.

Sie können auf diese von Hand ...

use Cwd;
sub foo {
    my $orig_cwd = cwd;
    chdir "some/dir";

    ...do some work...

    chdir $orig_cwd;
}

, aber das hat Probleme. Wenn das Unterprogramm zu früh oder stirbt zurückgibt (und die Ausnahme gefangen ist) Code wird noch in some/dir sein. Auch könnte die chdirs fehlschlagen und Sie müssen bedenken, jede Verwendung zu überprüfen. Bleh.

Glücklicherweise gibt es ein paar Module dies zu erleichtern. File :: pushd ist eines, aber ich ziehe File :: chdir .

use File::chdir;
sub foo {
    local $CWD = 'some/dir';

    ...do some work...
}

File :: chdir macht Verzeichnisse in Zuordnung $CWD ändern. Und Sie können $CWD lokalisieren, so dass es am Ende Ihres Umfangs zurückgesetzt wird, egal was passiert. Es ist auch überprüft automatisch, ob die chdir gelingt und wirft eine ansonsten Ausnahme. Manchmal ist es es in Skripten verwenden, weil es nur so bequem.

Ich mache das nicht oft, aber manchmal kann es durchaus ein wenig Kopfschmerzen speichern. Nur sicher sein, dass, wenn Sie Verzeichnisse ändern, können Sie immer wieder auf das Verzeichnis, das Sie aus gestartet ändern. Andernfalls Pfade Code zu ändern, könnte die Anwendung verlassen irgendwo sollte es nicht sein.

Für Perl, haben Sie die File :: pushd Modul von CPAN die lokal macht das Arbeitsverzeichnis ganz elegant zu ändern. Unter Angabe der Zusammenfassung:

  use File::pushd;

  chdir $ENV{HOME};

  # change directory again for a limited scope
  {
      my $dir = pushd( '/tmp' );
      # working directory changed to /tmp
  }
  # working directory has reverted to $ENV{HOME}

  # tempd() is equivalent to pushd( File::Temp::tempdir )
  {
      my $dir = tempd();
  }

  # object stringifies naturally as an absolute path
  {
     my $dir = pushd( '/tmp' );
     my $filename = File::Spec->catfile( $dir, "somefile.txt" );
     # gives /tmp/somefile.txt
  }

Ich werde zweite Schwern des und Hugos Kommentare oben. Hinweis Schwern die Vorsicht über im Falle eines unerwarteten Ausgang zum ursprünglichen Verzeichnis zurück. Er gibt entsprechenden Perl-Code, damit umzugehen. Ich werde die Shell (Bash, Korn, Bourne) trap Kommando hinweisen.

trap "cd $ saved_dir" 0

wird wieder auf Subshell Ausgang zum saved_dir (wenn Sie die Datei sind .'ing).

mike

Beachten Sie auch, dass Unix und Windows sind in Verzeichnis-Stack einen eingebauten: pushd und popd . Es ist extrem einfach zu bedienen.

Ist es überhaupt möglich, zu versuchen und vollständig quantifiziert Pfade zu verwenden, und machen keine Annahmen, auf denen Verzeichnis Sie sind momentan in? z.

use FileHandle;
use FindBin qw($Bin);
# ...
my $file = new FileHandle("< $Bin/somefile");

statt

use FileHandle;
# ...
my $file = new FileHandle("< somefile");

Dies wird wahrscheinlich einfacher auf lange Sicht, da Sie geschieht nicht über seltsame Dinge kümmern müssen (das Skript zu sterben oder getötet zu werden, bevor sie das aktuelle Arbeitsverzeichnis zurück, wo es war setzen könnte), und ist recht möglicherweise mehr tragbar.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top