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

Posted

技术标签:

【中文标题】运行 Node 脚本时更改当前 shell 上下文中的工作目录【英文标题】:Change working directory in my current shell context when running Node script 【发布时间】:2013-11-17 04:45:23 【问题描述】:

我正在尝试更改从 bin 脚本运行的 Node.js 脚本的工作目录。我有类似以下内容:

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

当我用./bin/nodefile 运行这个文件时,它会退出,但当前shell 上下文的工作目录没有改变。我也试过shelljs,但也没用。

最好的方法是什么?我知道它正在工作,但它只是在一个单独的过程中。

【问题讨论】:

你有什么证据表明 cwd 没有改变?请记住,require() 和 cwd 中使用的路径是两个不同的东西。 有没有办法在 Windows 中做到这一点? 【参考方案1】:

更改目录的正确方法实际上是使用process.chdir(directory)。这是来自documentation 的示例:

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,终端会说我在其他方面。因为这是一个不同的过程? 该方法更改进程的当前工作目录,而不是shell。据我所知,更改正在运行的进程的外部 cwd 非常复杂,不推荐使用。您想这样做的原因是什么? 嗯。好,谢谢。那么我想这样做的原因是因为我正在制作一个终端应用程序来组织我的项目。所以基本上我希望能够列出我的项目并轻松地将当前的 shell 位置更改为该位置。现在我想了想,我将研究 z (github.com/rupa/z) 是如何做到这一点的。虽然这是在 bash 中完成的。我也许可以在 applescript 中做到这一点? @hexacyanide 感谢您的添加很麻烦,因为更改未对齐【参考方案2】:

Node 没有内置方法来更改运行 Node 进程的底层 shell 的 CWD。​​p>

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

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

当 Node 进程存在时,您会发现自己回到了启动该进程的 CWD。​​p>

【讨论】:

【参考方案3】:

您尝试做的事情是不可能的。原因是在 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 脚本。

这是完成你想做的事情的唯一方法。

【讨论】:

【参考方案4】:

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

我做过一个类似的工具(一个小命令,给定项目的描述,设置环境、路径、目录等)。我所做的是设置所有内容,然后生成一个 shell:

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

执行后,您将在一个带有新目录(在我的例子中是环境)的 shell 上。当然,您可以将 bash 更改为您喜欢的任何 shell。与您最初要求的主要区别是:

还有一个额外的过程,所以... 你必须写'exit'才能回来,然后... 存在后,所有更改都将撤消。

但是,对我来说,差异是可取的。

【讨论】:

【参考方案5】:

试试这个代码:

const dirPath = path.join(__dirname, foldername);
process.chdir(dirPath);

【讨论】:

以上是关于运行 Node 脚本时更改当前 shell 上下文中的工作目录的主要内容,如果未能解决你的问题,请参考以下文章

执行shell脚本三种方法的区别:(sh、exec、source)

shell脚本中的全局环境变量

使用Shell脚本运行 "清理 "右键菜单操作。

如何使用 Node.js 确定当前的操作系统

从 ChromeBook 安全 shell 脚本启动网页?

Docker:如何知道 mongo 是不是在 Alpine/node 中使用 shell 脚本文件运行