我正在尝试弄清楚如何在 Node 中编写某种安装脚本(是的,完全是噩梦)。我基本上是想弄清楚我该怎么做;获取 git 存储库,cd 到该存储库,运行各种构建命令等等。
但是再次阅读节点文档让我一无所知,因为“文档”基本上是对可用方法的描述......现在你去弄清楚它在现实世界中的实际工作原理 - (请举例! -很抱歉让挫败感在这里显现出来)。
我正在尝试运行我能想到的两个最基本的命令:
cd dir_name
和 pwd
尝试 cd 进入目录并打印工作目录以实际查看我是否进入该目录。
我让这部分工作了(是的,谷歌搜索,猜测等):
const path = require('path');
const cp = require('child_process');
cp.execSync('git clone [email protected]<left blank>.git', {
stdio: [0, 1, 2],
cwd: path.resolve(__dirname, ''),
})
现在,我尝试进入此目录并执行进一步的命令:
const cm1 = cp.spawnSync('cd dir_name', );
console.log( `cm1 stderr: ${ cm1.stderr }` );
console.log( `cm1 stdout: ${ cm1.stdout }` );
const cm2 = cp.spawnSync('pwd', );
console.log( `cm2 stderr: ${ cm2.stderr }` );
console.log( `cm2 stdout: ${ cm2.stdout }` );
我希望在控制台中看到这个:
cm2 stdout: path/to/dir_name
但这显然——出于我不清楚的原因——行不通。
据我了解(通过猜测我得到的谷歌结果)我实际上正在启动两个不同的shell(!?) - 哦,真是一个惊喜。
有人可以简单地说明如何从节点脚本文件运行一系列命令(否则我将手动输入终端并逐个执行的命令)(请忽略节点所需的先决条件扫描)安装等。让我们不要让事情进一步复杂化)?
我希望从节点运行简单的命令会更容易。
我实际上正在启动两个不同的 shell(!?)
是的,这就是为什么 pwd 不一样。
要获得
cm2 stdout: path/to/dir_name
作为输出,您需要在同一个 shell 中运行该命令,如下所示
const cm1 = cp.spawnSync('cd dir_name && pwd'); // notice `&& pwd`
console.log( `cm1 stderr: ${ cm1.stderr }` );
console.log( `cm1 stdout: ${ cm1.stdout }` );
所以发生的事情是节点使用您传递的参数创建 shell (
/bin/sh
) 的子进程。它类似于运行这个命令
$ /bin/sh -c "cd dir_name && pwd"
但你正在这样做
$ /bin/sh -c "cd dir_name"
$ /bin/sh -c "pwd"
这是临时代码
//@ts-check
const util = require('util')
const cp = require('child_process')
const path = require('path')
const exec = util.promisify(cp.exec)
async function main() {
const testcd = await exec(`cd dir_name && pwd && ls`)
process.stdout.write(testcd.stdout)
process.stderr.write(testcd.stderr)
console.log('cwd of parent process (nodejs)', process.cwd())
const clonedir = path.join(process.cwd(), 'junk', 'cloned-repo')
const gitclone = await exec(`git clone [email protected] ${clonedir}`)
// above is same as /bin/sh -c "git clone [email protected] ./junk/cloned-repo"
process.stdout.write(gitclone.stdout)
process.stderr.write(gitclone.stderr)
}
main().catch(console.error)