0

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 :-)

1 Answers1

0

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()  

Sanket
  • 344
  • 2
  • 6