【问题标题】:node child_process.spawn fails with ENOENT when using chained commands使用链式命令时节点 child_process.spawn 失败并显示 ENOENT
【发布时间】:2019-06-04 23:14:59
【问题描述】:

我对 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”....

编辑

在 samuels 回答后,我更改了以下几行

...
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")));

错误错误:生成 C:\SoftwareAG105\Apama\bin\apama_env.bat && C:\SoftwareAG105\Apama\bin\correlator.exe ENOENT index.js:15 C:\SoftwareAG105\Apama\bin\apama_env.bat 有没有 index.js:9 C:\SoftwareAG105\Apama\bin\correlator.exe 在那里

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

【问题讨论】:

  • 在您的命令行上,您是否尝试过像这样首先并行运行它们? '/bin/apama_env.bat && /bin/correlator.exe 。有一些情况下程序在一起生成时无法启动
  • 还有你使用的nodejs版本是什么?
  • 是的,我从记录的字符串 /bin/apama_env.bat && /bin/correlator.exe 手动运行它们,并确保事情是正确的 w.r.t。路径等...我在 Windows 上使用节点 v11.6.0,但将更新到 12.x,无论是当前的

标签: node.js typescript


【解决方案1】:

好吧,我终于找到了隐藏在各种谷歌帖子中的信息:

我发现 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});

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

【讨论】:

    【解决方案2】:

    这可能与 Windows 上的路径分隔符是反斜杠而不是正斜杠有关。

    在构建字符串时,请尝试使用path.delimiter(从默认节点path 模块导入)(根据操作系统为/\)。像这样:

    let programhome: string = ['C:', 'SoftwareAG105', 'Apama'].join(path.delimiter);.
    

    这样,无论操作系统如何,您的路径都将始终有效。

    【讨论】:

    • 嗨@Samuel - 谢谢你我更新了我的问题以包含使用这个的代码 - 实际上很棒的提示:) - 但不幸的是我仍然遇到同样的问题 - 如果我单独运行单独的命令 envscript 或程序它工作(运行良好)但与'&&'链接它失败了......
    猜你喜欢
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 2016-03-16
    相关资源
    最近更新 更多