Ändern Sie das Arbeitsverzeichnis in meinem aktuellen Shell-Kontext, wenn Sie das Knotenskript ausführen

113

Ich versuche, das Arbeitsverzeichnis meines Node.js-Skripts zu ändern, wenn es über ein bin-Skript ausgeführt wird. Ich habe so etwas wie folgendes:

#!/usr/bin/env node
process.chdir('/Users')

Wenn ich diese Datei dann mit ausführe ./bin/nodefile, wird sie beendet, aber das Arbeitsverzeichnis des aktuellen Shell-Kontexts hat sich nicht geändert. Ich habe auch Shelljs ausprobiert , aber das funktioniert auch nicht.

Was ist der beste Weg, dies zu tun? Ich verstehe, dass es funktioniert, aber es ist nur in einem separaten Prozess.

Jonovono
quelle
Welche Beweise haben Sie dafür, dass sich der CWD nicht geändert hat? Denken Sie daran, dass die in require () und cwd verwendeten Pfade zwei verschiedene Dinge sind.
Jeesty
Gibt es eine Möglichkeit, dies in Windows zu tun?
Phillip

Antworten:

145

Der richtige Weg, um Verzeichnisse zu ändern, ist tatsächlich mit process.chdir(directory). Hier ist ein Beispiel aus der Dokumentation :

console.log('Starting directory: ' + process.cwd());
try {
  process.chdir('/tmp');
  console.log('New directory: ' + process.cwd());
}
catch (err) {
  console.log('chdir: ' + err);
}

Dies ist auch in der Node.js REPL testbar:

[monitor@s2 ~]$ node
> process.cwd()
'/home/monitor'
> process.chdir('../');
undefined
> process.cwd();
'/home'
Hexacyanid
quelle
Hoppla. Ja, das ist der Befehl, den ich tatsächlich benutze. Wenn ich es jedoch in einem einfachen Skript verwende, scheint es immer noch nicht zu funktionieren (sobald das Skript beendet wird, bin ich immer noch im alten Verzeichnis). Wenn ich process.cwd () aufrufe, heißt es, dass ich mich in dem Verzeichnis befinde, das ich sein sollte, aber mein Terminal, wenn ich pwd anrufe, sagt, ich bin in etwas anderem. Weil es ein anderer Prozess ist?
Jonovono
10
Die Methode ändert das aktuelle Arbeitsverzeichnis des Prozesses , nicht die Shell. Soweit ich weiß, ist das Ändern des externen CWD eines laufenden Prozesses ziemlich komplex und wird nicht empfohlen. Was ist Ihr Grund dafür?
Hexacyanid
3
Hmm. OK danke. Der Grund, warum ich das tun möchte, ist, dass ich eine Terminal-App zum Organisieren meiner Projekte erstelle. Grundsätzlich möchte ich in der Lage sein, meine Projekte aufzulisten und den aktuellen Shell-Speicherort einfach darauf zu ändern. Jetzt, wo ich darüber nachdenke, werde ich untersuchen, wie z ( github.com/rupa/z ) dies tut. Obwohl das in Bash gemacht wird. Ich könnte das vielleicht in Applescript machen?
Jonovono
@hexacyanide danke für das Hinzufügen war störend, weil die Änderungen nicht ausgerichtet waren
Eugen Sunic
33

Es gibt keine integrierte Methode für Node, um die CWD der zugrunde liegenden Shell zu ändern, auf der der Node-Prozess ausgeführt wird.

Sie können das aktuelle Arbeitsverzeichnis des Knotenprozesses über den Befehl ändern process.chdir().

var process = require('process');
process.chdir('../');

Wenn der Knotenprozess vorhanden ist, befinden Sie sich wieder in dem CWD, in dem Sie den Prozess gestartet haben.

drei
quelle
14

Was Sie versuchen, ist nicht möglich. Der Grund dafür ist, dass in einem POSIX-System (Linux, OSX usw.) ein untergeordneter Prozess die Umgebung eines übergeordneten Prozesses nicht ändern kann. Dies umfasst das Ändern des Arbeitsverzeichnisses und der Umgebungsvariablen des übergeordneten Prozesses.

Wenn Sie sich in der Befehlszeile befinden und Ihr Knotenskript ausführen, erzeugt Ihr aktueller Prozess ( bash, zshwas auch immer) einen neuen Prozess mit einer eigenen Umgebung, normalerweise eine Kopie Ihrer aktuellen Umgebung (dies kann über Systemaufrufe geändert werden ; aber das würde den Rahmen dieser Antwort sprengen), so dass dieser Prozess alles, was er tun muss, vollständig isoliert ausführen kann. Wenn der Unterprozess beendet wird, wird die Kontrolle an den Prozess Ihrer Shell zurückgegeben, in dem die Umgebung nicht betroffen ist.

Es gibt viele Gründe dafür, aber stellen Sie sich zum einen vor, Sie hätten ein Skript im Hintergrund (via ./foo.js &) ausgeführt und während der Ausführung Ihr Arbeitsverzeichnis geändert oder Ihr überschrieben PATH. Das wäre ein Albtraum.

Wenn Sie einige Aktionen ausführen müssen, die das Ändern Ihres Arbeitsverzeichnisses Ihrer Shell erfordern, müssen Sie eine Funktion in Ihre Shell schreiben. Wenn Sie beispielsweise Bash ausführen, können Sie Folgendes in Folgendes einfügen ~/.bash_profile:

do_cool_thing() {
  cd "/Users"
  echo "Hey, I'm in $PWD"
}

und dann ist diese coole Sache machbar:

$ pwd
/Users/spike
$ do_cool_thing
Hey, I'm in /Users
$ pwd
/Users

Wenn Sie zusätzlich komplexere Aufgaben ausführen müssen, können Sie von dieser Funktion aus jederzeit Ihr NodeJS-Skript aufrufen.

Nur so können Sie das erreichen, was Sie versuchen.

Spike Grobstein
quelle
10

Kurze Antwort: Nein (einfach?), Aber Sie können etwas tun, das Ihrem Zweck dient.

Ich habe ein ähnliches Tool ausgeführt (ein kleiner Befehl, der anhand einer Projektbeschreibung die Umgebung, Pfade, Verzeichnisse usw. festlegt). Was ich tue, ist alles einzurichten und dann eine Shell zu erzeugen mit:

spawn('bash', ['-i'], {
  cwd: new_cwd,
  env: new_env,
  stdio: 'inherit'
});

Nach der Ausführung befinden Sie sich in einer Shell mit dem neuen Verzeichnis (und in meinem Fall der Umgebung). Natürlich können Sie die Bash für jede beliebige Shell ändern. Die Hauptunterschiede zu dem, wonach Sie ursprünglich gefragt haben, sind:

  • Es gibt einen zusätzlichen Prozess, also ...
  • Sie müssen "exit" schreiben, um zurück zu kommen, und dann ...
  • Nach dem Vorhandensein werden alle Änderungen rückgängig gemacht.

Für mich sind diese Unterschiede jedoch wünschenswert.

Entwicklung
quelle