Node.js 捕捉击键的节点脚本不';被shell脚本调用时无法工作

Node.js 捕捉击键的节点脚本不';被shell脚本调用时无法工作,node.js,bash,Node.js,Bash,因此,我有一个node.js脚本,可以捕获用户在终端中的击键。当我从命令行调用它时,它工作得很好,但是当我从bash脚本(git pre-commit)调用脚本时,一切都正常,直到用户输入阶段,程序将无法拾取输入 我还应该提到我现在在windows上使用git bash作为shell node.js脚本的代码: const fs = require('fs'); const path = require('path'); const readline = require('readline');

因此,我有一个node.js脚本,可以捕获用户在终端中的击键。当我从命令行调用它时,它工作得很好,但是当我从bash脚本(git pre-commit)调用脚本时,一切都正常,直到用户输入阶段,程序将无法拾取输入

我还应该提到我现在在windows上使用git bash作为shell

node.js脚本的代码:

const fs = require('fs');
const path = require('path');
const readline = require('readline');
const regedit = require('regedit');

const { bufferStringToString } = require("./functions")

const scriptArgs = process.argv.slice(2)

let spawn = getExtendedSpawn();
function getExtendedSpawn() {
    var childProcess = require("child_process");
    var oldSpawn = childProcess.spawn;
    function mySpawn() {
        console.log('spawn called');
        console.log(arguments);
        var result = oldSpawn.apply(this, arguments);
        return result;
    }
    return mySpawn;
};

//prevents node from exiting
setInterval(function() {
    console.log("Are you still there?");
}, 1000 * 60 * 60);

//directory build commands will be run in
const projectRoot = path.resolve(__dirname, "../../..", "portfolio.chriscormier.ca");




function validateWindowsEnviroment() {
    regedit.list('HKCU\\Environment', function (err, result) {
    
        const
            firstKey = Object.keys(result)[0],
            pathVarValue = result[firstKey].values.Path.value,
            individualPathItems = pathVarValue.split(";");

        if (individualPathItems.includes('C:\\windows\\system32') === false) {
            
            console.error(["\n",  
                "        ",
                "it seems to be the first time you've used this script on this windows machine.\n", 
                "        ",
                "The enviroment variable \'Path\' doesn't have an entry for 'C:\\windows\\system32.\n",
                "        ",
                "Add the value 'C:\\windows\\system32;' in the regeistry to use this script.\n",
                "        ",
                "P.S.Don't forget you need to do a system restart after a regeistry change.\n"
            ].join(""))
        
        } else if (individualPathItems.includes('C:\\windows\\system32')) {
            return 
        } 

    })
}

function changeDir(path) {
    try {
        process.chdir(path)
    } catch (err) {
        console.error( "ERROR: Path to project root is invalid. This source file was likley moved. To fix, update this file's 'projectRoot' constant" + "\n")
        console.error(err.message, err.stack)
        process.exit(1)
    }
}

let processesExited = 0;
async function runCmd(rawCommand) {
    //if agument passed has no spaces, then it wouldn't have an args
    let commandToRun;
    let isMultiArgCommand = rawCommand.search(" ") !== -1
        
    
    let commandArgs = [];
    let trimmedCommand; 
    if (isMultiArgCommand === true) {
        
        //changes a command like "npm run start" to npm run start
        const paddedWithSingleQs = (rawCommand.search("\'") !== -1) ? true : false;
        const paddedWithDoubleQs = (  rawCommand.search("\"") !== -1 ) ? true : false; 
        const paddedWith = (paddedWithSingleQs) ? "\'" : "\"";
        trimmedCommand = rawCommand.replace(new RegExp(paddedWith, "g"), "")
        

        //splits command arguments and quoted arguments from main command
        const quotesOfNestedArgs = ( paddedWith === '\'' ) ? '\"': '\''
        const forFindingNestedArgs = new RegExp(`${quotesOfNestedArgs}\w+?${quotesOfNestedArgs}`, "g")
        
    
        const
            commandWithMultiPlaceholders = trimmedCommand
            quotedArgs = trimmedCommand.match(forFindingNestedArgs)
            hasNestedArgs = quotedArgs !== null   
        
        let properlyQuotedArgs;
        if (hasNestedArgs === true) {
            
            properlyQuotedArgs = ( quotesOfNestedArgs === '\'' ) ? quotedArgs.replace(/'/g,'\"') : quotedArgs
            
        }

        commandArgs = commandArgs.concat(properlyQuotedArgs)
    }

    
    let child;
    if (isMultiArgCommand === true) {
        child = spawn(rawCommand, { shell:true } );
    } else if ( isMultiArgCommand === false ) {
        child = spawn(trimmedCommand, commandArgs, { shell:true } );
    }

    //error logging
    const errorBuffer = [];  
    child.stderr.on('data', (chunk) => {
        errorBuffer.concat(chunk)
    })
    
    child.stderr.on('end', () => {
        const errorContent = Buffer.concat(errorBuffer).toString();
        console.error(errorContent)    
    })

    // use child.stdout.setEncoding('utf8'); if you want text chunks
    child.stdout.on('data', (chunk) => {
        const chunckAsText = bufferStringToString(chunk)
        console.log(chunckAsText)
    });

    
    child.on('close', (code) => {
        ++processesExited
        return
    });

}

let counter = 0
function runCommands(cmdsArray) {
    cmdsArray.forEach(cmd => {
        ++counter
        console.log("ran one command")
        runCmd(cmd)
    });
}

//------------------  main execution -----------------------

validateWindowsEnviroment()
//changes working directory to C:\Users\chris\Google Drive\code projects\portfolio.chriscormier.ca 
changeDir(projectRoot)

console.log("\n     Add Build to Staging? (Y/n)")


//------------------  reation after keypress answer -----------------------
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY) {
    process.stdin.setRawMode(true);
}

const onKeyPress = (key, keypressData) => {
  if (keypressData.ctrl && keypressData.name === 'c') {
    process.exit(); 
  } else {
      if (keypressData.name === 'y' || keypressData.name === 'return') {
          runCommands(scriptArgs)
          const interval = setInterval(() => {
              
              if (processesExited === scriptArgs.length) {
                  runCmd("git add build")
                    .then(() => {
                        clearInterval(interval)
                        console.log("\n     Added Build to Index\n")
                        process.exit()
                    })
                  
              }
          },70)
      } else if (keypressData.name === 'n') {
          process.exit()
      } 
  }
}

process.stdin.on('keypress', onKeyPress);
包装节点脚本的bash脚本中的代码:

#!/bin/sh

foundProjectDir=""
for i in {1..5} 
do
    cd ..
    foundProjectDir='find . -type d -name 'portfolio.chriscormier.ca''

    if [ -n "$($foundProjectDir)" ] 
    then
        cd "$($foundProjectDir)"
        echo "Navigated to project root at $(pwd)"
        break
    fi 
    
done



node ./scripts/ask-to-run-build/ask-to-run-build.js "gulp build"
我从未在node中处理过输入流,所以idk(如果这是node的常见问题/限制)。任何建议都有帮助