首页 > 解决方案 > 使用链式命令时节点 child_process.spawn 失败并显示 ENOENT

问题描述

我对 TypeScript/Javascript/Node.js 比较陌生,但是在获取环境脚本 myapp_env(在 Windows 上运行 myapp_env.bat)之后,我必须执行二进制 myapp(或 Windows 上的 myapp.exe)

. myapp_env && myapp 

或在 Windows (cmd) 中

myapp_env.bat && myapp.exe

我正在尝试使用 spawn:

import {exec,spawn} from 'child_process';
import {exists} from 'fs'

let programhome: string = 'C:/SoftwareAG105/Apama';
let envscript: string = programhome + '/bin/apama_env.bat';
let program: string = programhome + '/bin/correlator.exe';

exists(envscript , found => 
       console.log( envscript + (found ? " is there" : " is not there")));
exists(program , found => 
       console.log( program + (found ? " is there" : " is not there")));


try {
    let test = spawn(envscript + ' && ' + program);
    test.stdout.on('data', data => console.log(data));
    test.stderr.on('data', data => console.log(data));
    test.on('error', data => console.log('ERROR ' + data));
    test.on('end', data => console.log('END ' + data));
    test.on('exit', data => console.log('Exit ' + data));
} catch (error) {
    console.log(error);
}

我收到一个ENOENT错误,我认为是因为它试图查看整个字符串是否作为文件存在(?)。如果我单独运行它们,那么它工作正常。在这两种情况下,该exists行都会打印“is there”....

编辑

塞缪尔回答后,我更改了以下几行

...
import {parse,format,join} from 'path'
...
let programhome: string = join( 'C:' , 'SoftwareAG105', 'Apama' );
let envscript: string = join( programhome ,'bin','apama_env.bat');
let program: string = join(programhome , 'bin' , 'correlator.exe');

exists(envscript , found => console.log( envscript + (found ? " is there" : " is not there")));
exists(program , found => console.log( program + (found ? " is there" : " is not there")));

ERROR 错误:spawn C:\SoftwareAG105\Apama\bin\apama_env.bat && C:\SoftwareAG105\Apama\bin\correlator.exe ENOENT index.js:15 C:\SoftwareAG105\Apama\bin\apama_env.bat 是否有索引.js:9 C:\SoftwareAG105\Apama\bin\correlator.exe 在那里

TLDR;所以我的问题是我可以在 spawn 中链接命令以便我可以获取环境并运行程序吗?

标签: node.jstypescript

解决方案


好的,所以最后我发现隐藏在各种谷歌帖子中的信息:

我发现 exec 会按照我想要的方式工作,但 spawn 不会,事实证明,对于 exec,一个 shell 开始允许链接发生。

https://www.freecodecamp.org/news/node-js-child-processes-everything-you-need-to-know-e69498fe970a/

默认情况下,spawn 函数不会创建一个 shell 来执行我们传递给它的命令。这使得它比 exec 函数更有效,后者确实创建了一个 shell。exec 函数还有另一个主要区别。它缓冲命令生成的输出并将整个输出值传递给回调函数(而不是使用流,这是 spawn 所做的)。

child_process.spawn 接受一个选项对象,该对象可以具有一个名为 shell 的属性

let test = spawn(envscript + ' && ' + program,{shell:true});

这个额外的配置允许我执行我需要的链接,因此我现在可以获取环境并正确运行程序。


推荐阅读