Changer le répertoire de travail dans mon contexte de shell actuel lors de l'exécution du script Node

114

J'essaie de changer le répertoire de travail de mon script Node.js lorsqu'il est exécuté à partir d'un script bin. J'ai quelque chose comme ce qui suit:

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

Lorsque j'exécute ensuite ce fichier avec ./bin/nodefile, il se ferme, mais le répertoire de travail du contexte actuel du shell n'a pas changé. J'ai également essayé shelljs , mais cela ne fonctionne pas non plus.

Quelle est la meilleure façon de procéder? Je comprends que cela fonctionne, mais c'est juste dans un processus distinct.

Jonovono
la source
quelle preuve avez-vous que le cwd n'a pas changé? N'oubliez pas que les chemins utilisés dans require () et le cwd sont deux choses différentes.
jeesty
Existe-t-il un moyen de faire cela sous Windows?
Phillip

Réponses:

146

La bonne façon de changer de répertoire est en fait avec process.chdir(directory). Voici un exemple tiré de la documentation :

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

Ceci est également testable dans le REPL Node.js:

[monitor@s2 ~]$ node
> process.cwd()
'/home/monitor'
> process.chdir('../');
undefined
> process.cwd();
'/home'
hexacyanide
la source
Oups. Oui, c'est la commande que j'utilise actuellement. Cependant, lorsque je l'utilise dans un script simple, il ne semble toujours pas fonctionner (une fois le script terminé, je suis toujours dans l'ancien répertoire) Si j'appelle process.cwd (), cela indique que je suis dans le répertoire que je devrais être mais mon terminal si j'appelle pwd dit que je suis dans quelque chose d'autre. Parce que c'est un processus différent?
Jonovono
10
La méthode modifie le répertoire de travail actuel du processus , pas le shell. Autant que je sache, changer le cwd externe d'un processus en cours d'exécution est assez complexe et n'est pas recommandé. Quelle est votre raison de vouloir faire cela?
hexacyanide
3
Hmm. OK merci. Eh bien, la raison pour laquelle je veux faire cela est que je crée une application de terminal pour organiser mes projets. Donc, fondamentalement, je veux pouvoir lister mes projets et changer facilement l'emplacement actuel du shell en cela. Maintenant que j'y pense, je vais regarder comment z ( github.com/rupa/z ) fait cela. Bien que cela se fasse dans bash. Je pourrais peut-être le faire en applescript?
Jonovono
@hexacyanide merci pour l'ajout était ennuyeux car les changements n'étaient pas alignés
Eugen Sunic
33

Il n'y a pas de méthode intégrée permettant à Node de modifier le CWD du shell sous - jacent exécutant le processus Node.

Vous pouvez modifier le répertoire de travail actuel du processus Node via la commande process.chdir().

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

Lorsque le processus Node existe, vous vous retrouverez dans le CWD dans lequel vous avez commencé le processus.

trois
la source
14

Ce que vous essayez de faire n'est pas possible. La raison en est que dans un système POSIX (Linux, OSX, etc.), un processus enfant ne peut pas modifier l'environnement d'un processus parent. Cela inclut la modification du répertoire de travail et des variables d'environnement du processus parent.

Lorsque vous êtes sur la ligne de commande et vous allez exécuter votre script nœud, votre processus actuel ( bash, zsh, peu importe) engendre un nouveau processus qui a son propre environnement, en général une copie de votre environnement actuel (il est possible de changer cela via des appels système ; mais cela dépasse la portée de cette réponse), permettant à ce processus de faire tout ce qu'il doit faire dans un isolement complet. Lorsque le sous-processus se termine, le contrôle est rendu au processus de votre shell, où l'environnement n'a pas été affecté.

Il y a beaucoup de raisons à cela, mais d'une part, imaginez que vous avez exécuté un script en arrière-plan (via ./foo.js &) et qu'il a commencé à changer votre répertoire de travail ou à remplacer votre PATH. Ce serait un cauchemar.

Si vous devez effectuer certaines actions qui nécessitent de changer le répertoire de travail de votre shell, vous devrez écrire une fonction dans votre shell. Par exemple, si vous exécutez Bash, vous pouvez mettre ceci dans votre ~/.bash_profile:

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

et puis cette chose cool est faisable:

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

Si vous avez besoin de faire des choses plus complexes en plus, vous pouvez toujours appeler votre script nodejs depuis cette fonction.

C'est la seule façon d'accomplir ce que vous essayez de faire.

Spike Grobstein
la source
10

Réponse courte: pas de moyen (facile?), Mais vous pouvez faire quelque chose qui sert votre objectif.

J'ai fait un outil similaire (une petite commande qui, étant donné une description d'un projet, définit l'environnement, les chemins, les répertoires, etc.). Ce que je fais, c'est tout configurer, puis créer un shell avec:

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

Après l'exécution, vous serez sur un shell avec le nouveau répertoire (et, dans mon cas, l'environnement). Bien sûr, vous pouvez changer bash pour le shell que vous préférez. Les principales différences avec ce que vous aviez initialement demandé sont:

  • Il y a un processus supplémentaire, donc ...
  • vous devez écrire 'exit' pour revenir, puis ...
  • après avoir existé, toutes les modifications sont annulées.

Cependant, pour moi, ces différences sont souhaitables.

Évolution
la source