运行Node脚本时在当前shell上下文中更改工作目录


113

我试图从bin脚本运行Node.js脚本时更改其工作目录。我有类似以下内容:

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

然后./bin/nodefile,我使用运行该文件时,它会退出,但是当前shell上下文的工作目录没有更改。我也尝试过shelljs,但这也不起作用。

做这个的最好方式是什么?我了解它正在工作,但只是在一个单独的过程中。


您有什么证据可以证明Cwd没有变化?请记住,require()和cwd中使用的路径是两件事。
jeesty

在Windows中有没有办法做到这一点?
菲利普(Phillip)

Answers:


145

更改目录的正确方法实际上是使用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'

哎呀。是的,这是我实际使用的命令。但是,当我在简单的脚本中使用它时,它似乎仍然无法正常工作(一旦脚本退出,我仍然位于旧目录中)。如果我调用process.cwd(),它说我在目录中,但我应该在终端,如果我打电话给pwd说我在别的地方。因为这是一个不同的过程?
Jonovono

10
该方法更改进程的当前工作目录,而不是外壳程序。据我所知,更改正在运行的进程的外部cwd非常复杂,不建议这样做。您要这样做的原因是什么?

3
嗯 好,谢谢。好吧,我想要这样做的原因是因为我正在制作用于组织项目的终端应用程序。因此,基本上我希望能够列出我的项目并轻松地将当前shell位置更改为该位置。现在我考虑了一下,我将研究z(github.com/rupa/z)如何做到这一点。虽然那是在bash中完成的。我也许可以在applescript中执行此操作?
Jonovono

@hexacyanide感谢您的加入,因为更改未对齐,这很麻烦
Eugen Sunic

33

Node没有内置的方法来更改运行Node进程的基础外壳的CWD 。

可以通过命令更改Node进程的当前工作目录process.chdir()

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

当Node进程存在时,您会发现自己回到了开始该进程的CWD中。


14

您试图做的事是不可能的。原因是在POSIX系统(Linux,OSX等)中,子进程无法修改父进程的环境。这包括修改父进程的工作目录和环境变量。

当您在命令行上并执行Node脚本时,您当前的进程(bashzsh等等)会生成一个具有自己环境的新进程,通常是您当前环境的一个副本(可以通过系统调用来更改它) ;但这超出了此答复的范围),允许该过程完全隔离地执行所需的操作。子进程退出时,控制权将交还给您的Shell进程,在该进程中环境不会受到影响。

造成这种情况的原因很多,但有一个原因,请想象一下,您在后台执行了一个脚本(通过./foo.js &),并在脚本运行时开始更改工作目录或覆盖您的PATH。那将是一场噩梦。

如果需要执行一些需要更改Shell工作目录的操作,则需要在Shell中编写一个函数。例如,如果您正在运行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脚本。

这是完成您要完成的工作的唯一方法。


10

简短的回答:不(简单吗?)方法,但是您可以做一些符合您目的的事情。

我已经做了一个类似的工具(一个小命令,给出项目的描述,设置环境,路径,目录等)。我要做的是设置所有内容,然后使用以下命令生成一个shell:

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

执行后,您将进入具有新目录(在我的情况下为环境)的shell中。当然,您可以根据自己的喜好更改bash。与您最初要求的主要区别是:

  • 还有一个额外的过程,所以...
  • 您必须写“退出”返回,然后...
  • 存在后,所有更改都将撤消。

但是,对我而言,这种差异是可取的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.