web-dev-qa-db-ja.com

Nodeスクリプトの実行時に現在のシェルコンテキストの作業ディレクトリを変更する

Node.jsスクリプトがbinスクリプトから実行されるときに、作業ディレクトリを変更しようとしています。私は次のようなものを持っています:

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

このファイルを./bin/nodefileで実行すると終了しますが、現在のシェルコンテキストの作業ディレクトリは変更されていません。 shelljs も試しましたが、それでもうまくいきません。

これを行う最良の方法は何ですか?私はそれが機能していることを理解していますが、それはただ別のプロセスにあります。

94
Jonovono

ディレクトリを変更する正しい方法は、実際にはprocess.chdir(directory)を使用することです。 ドキュメント の例を次に示します。

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

これはNode.js REPLでもテストできます。

[monitor@s2 ~]$ node
> process.cwd()
'/home/monitor'
> process.chdir('../');
undefined
> process.cwd();
'/home'
127
hexacyanide

Nodeが基になるシェル Nodeプロセスを実行するCWDを変更するための組み込みメソッドはありません。

canコマンド process.chdir() を使用して、ノードプロセスの現在の作業ディレクトリを変更します。

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

Nodeプロセスが存在すると、プロセスを開始したCWDに戻ります。

31
dthree

あなたがしようとしていることは不可能です。これは、POSIXシステム(Linux、OSXなど)では、子プロセスが親プロセスの環境を変更できないためです。これには、親プロセスの作業ディレクトリと環境変数の変更が含まれます。

コマンドラインでNodeスクリプトを実行すると、現在のプロセス(bashzshなど)が独自の環境を持つ新しいプロセスを生成します。現在の環境のコピー(システムコールを介してこれを変更することは可能ですが、これはこの応答の範囲外です)、そのプロセスが完全に分離して実行する必要があることを実行できるようにします。サブプロセスが終了すると、制御はシェルのプロセスに戻され、環境は影響を受けません。

これには多くの理由がありますが、1つは、バックグラウンドで(./foo.js &を介して)スクリプトを実行し、実行中に作業ディレクトリの変更またはPATHのオーバーライドを開始したことを想像してください。それは悪夢です。

シェルの作業ディレクトリを変更する必要があるアクションを実行する必要がある場合は、シェルに関数を記述する必要があります。たとえば、Bashを実行している場合、これを~/.bash_profileに入れることができます。

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

そして、このクールなことは実行可能です:

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

さらに複雑なことを行う必要がある場合は、常にその関数からnodejsスクリプトを呼び出すことができます。

これは、あなたがやろうとしていることを達成できる唯一の方法です。

13
Spike Grobstein

簡単な答え:いいえ(簡単?)方法はありますが、目的に合った何かをすることができます。

同様のツール(プロジェクトの説明を指定して、環境、パス、ディレクトリなどを設定する小さなコマンド)を実行しました。私がやることはすべてをセットアップしてから、シェルを次のように生成することです:

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

実行後、新しいディレクトリ(および、私の場合は環境)を備えたシェルに移動します。もちろん、好みのシェルに合わせてbashを変更できます。最初に求めたものとの主な違いは次のとおりです。

  • 追加のプロセスがあるため、...
  • あなたは戻って来るために「出口」を書かなければなりません...
  • 既存の後、すべての変更は元に戻されます。

しかし、私にとっては、その違いが望ましいです。

8
Evolopment