简体   繁体   中英

How to display prompts and command outputs simultaneously in Nodejs?

I am trying to make a shell environment using Nodejs and encountered the following flaw in my program. I tried using the readline-sync and prompt-sync for resolving the issue and described about the problem next.

I am having the below code:

const prompt = require('prompt-sync')({sigint: true});
const { spawn } = require("child_process");
const os = require('os')
working_dir = os.homedir();

user_cmd = "";

while (user_cmd != "exit") {
    user_cmd = prompt(working_dir + " >");
    
    if (user_cmd.match("ls") != null) {
        const ls = spawn("ls");
        
        ls.stdout.on("data", data => {
            console.log(`${data}`);
        });

        ls.stderr.on("data", data => {
            console.log(`${data}`);
        });

        ls.on('error', (error) => {
            console.log(`${error.message}`);
        });
    }
} 

I want output in this way:

OUTPUT AFTER EACH PROMPT

hi@SanthoshSingh:/mnt/e/Atri Labs$ node shell.js 
/home/hi >ls
hi.js
ls.js
node_modules
package-lock.json
package.json
shell.js
/home/hi >exit

but getting the output in this way:

AFTER ALL PROMPTS GETTING THE OUTPUT

hi@SanthoshSingh:/mnt/e/Atri Labs$ node shell.js 
/home/hi >ls
/home/hi >exit
hi.js
ls.js
node_modules
package-lock.json
package.json
shell.js

Get me a solution people:-)

prompt-sync blocks the /dev/tty. Unless you exit from it you will not be able to print stdout buffer to tty(screen). You exit from it( prompt-sync ) only after you exit the while loop.

following is an alternate implementation that fixes the above issue:

const prompt = require('prompt-sync')({sigint: true});
const { spawn } = require("child_process");
const os = require('os')
working_dir = os.homedir();

user_cmd = "";

function call() {
  user_cmd = prompt(working_dir + " >");

  const ls = spawn(user_cmd);

  ls.stdout.on("data", data => {
    console.log(`${data}`);
    ls.kill('SIGINT')
  });

  ls.stderr.on("data", data => {
    console.log(`${data}`);
  });

  ls.on('error', (error) => {
    console.log(`${error.message}`);
    ls.kill('SIGINT')
  });

  ls.on('exit', (error) => {
    call()
  });

}

const interval = setInterval(function () { }, 1000)
process.on('exit', () => {
  clearTimeout(interval)
})
call()  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM