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

我正在尝试改变从 bin 脚本运行的 Node.js 脚本的工作目录。我有这样的东西:

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

当我使用 ./bin/nodefile运行这个文件时,它退出了,但是当前 shell 上下文的工作目录没有改变。我也尝试了 弹壳,但这也不工作。

什么是最好的方法来做到这一点? 我知道它的工作,但它只是在一个单独的过程。

144912 次浏览

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

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

你可以通过命令 process.chdir()改变 节点进程的当前工作目录。

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

当 Node 进程存在时,您将发现自己回到了启动该进程的 CWD 中。

简短的回答: 没有(容易?)的方法,但你可以做一些事情,服务于你的目的。

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

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

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

  • 还有一个额外的程序,所以..。
  • 你得写上“出口”才能回来,然后..。
  • 在存在之后,所有更改将被撤消。

然而,对我来说,这种差异是可取的。

你想做的事是不可能的。原因是在 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 脚本。

只有这样你才能完成你想做的事。

试试这个代码:

const dirPath = path.join(__dirname, foldername);
process.chdir(dirPath);
function cd(a, b) {
var a_path_arry = a.split('/');
var a_clear_path = [];
var b_clear_path = [];
a_path_arry.map((ele) => {
if(ele != '') a_clear_path.push(ele);
});


b_path_arry = b.split('/');
b_path_arry.map((ele) => {
if(ele != '') b_clear_path.push(ele);
});
b_path_length = b_clear_path.length;


for(var i=0;i<b_path_length;i++) {
if(b_clear_path[i] == '.') {
continue;
} else if(b_clear_path[i] != '..') {
a_clear_path.push(b_clear_path[i])
}
else {
a_clear_path.pop();
}
}


var path = '';
a_clear_path.map((ele)=> {
path += ele + '/';
});


console.log(path);


}


cd('a/b/c', './//d/e');