节点中的奇数执行输出

Odd exec output in node

我正在尝试确定 java 运行time 环境是否安装在计算机 运行ning 我的节点应用程序上。这是我开始构建以确定它是否已安装的承诺:

FileSystemTools.prototype.checkToSeeIfJavaRuntimeEnvIsAvailable = function (){
    return new Promise((resolve, reject) => {
        exec('java -version', (error, stdout, stderr) => {
            if(error) reject(error)
            if(stderr) reject(stderr)

            resolve(stdout)
        })
    })
}

我正在为 运行 构建的生成器函数到目前为止,此检查如下所示:

co(function *(){
    let jreVersion = yield fst.checkToSeeIfJavaRuntimeEnvIsAvailable()
    console.log(jreVersion)
}).catch(error => {
    throw new Error(error)
})

当我 运行 这样做时,我根本没有输出。但是,如果我解析从 exec 命令返回的所有参数:

   FileSystemTools.prototype.checkToSeeIfJavaRuntimeEnvIsAvailable = function (){
    return new Promise((resolve, reject) => {
        exec('java -version', (error, stdout, stderr) => {

            // resolving early with everything to see what's going on
            resolve({error, stdout, stderr})


            if(error) reject(error)
            if(stderr) reject(stderr)

            resolve(error, stdout, stderr)
        })
    })
}

我看到我的命令已成功触发,但它在标准错误而非标准输出中返回结果:

{
    error: null,
    stdout: '',
    stderr: 'java version "1.8.0_101"\nJava(TM) SE Runtime Environment (build 1.8.0_101-b13)\nJava HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)\n' 
}

我仔细检查了 the docs on the exec callback 以为我把回调参数弄错了,但它们的顺序肯定是正确的:

这给我提出了两个问题:

  1. 为什么我的命令成功输出返回标准错误?
  2. 如果它在标准错误中返回,为什么我的 if 语句检查标准错误并拒绝是否为真?

默认情况下,java -version 仅将其结果写入标准错误,即使命令已成功执行。您可以通过将 stderr 重定向到一个文件来确认这一点,就像这样

$ sh -c "java -version 2>/tmp/test"
$ cat /tmp/test
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

如果出现错误,回调中的 error 参数将是一个对象,包含错误代码和信号。