help
help copied to clipboard
After calling setRawMode() and spawn(…,{stdio:'pipe'}), input forces program to background
- Node.js Version: 10LTS, 12LTS
- OS: Linux, ubuntu 20.04
- Scope (install, code, runtime, meta, other?):
- Module (and version) (if relevant):
This simple program echos input characters, one per line, as numeric values until Ctrl-C or Ctrl-D is entered, which causes the program to quit cleanly.
const child_process = require('child_process');
async function waitUserInterrupt(){
return await new Promise((res)=>{
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on('data',(x)=>{
process.stderr.write(`\non data: ${x[0].toString()}\n`);
if (x[0]==3 || x[0]==4){ // ctrl 3
process.stdin.setRawMode(false);
process.stdin.removeAllListeners('data');
res({reason:'user interrupt'});
process.stdin.pause();
}
});
});
}
var child;
// A
waitUserInterrupt()
.then((x)=>{
console.log(x);
if (child) child.kill('SIGKILL');
})
.catch((e)=>{
console.log(e.message);
if (child) child.kill('SIGKILL');
});
// B
Example output:
$ node test.js
on data: 97
on data: 98
on data: 100
on data: 3
{ reason: 'user interrupt' }
$
However, when the following code
child = child_process.spawn(
'/bin/bash',
['--rcfile','devsrc/.bashrc','-i'],
{stdio:['pipe','pipe','pipe']}
);
var outq=[];
function printer(){
while (outq.length && process.stdout.write(outq[0])){
outq.shift();
}
}
function print(str) {
outq.push(str);
printer();
}
process.stdout.on('drain', printer);
child.stdout.on('data',(chunk)=>{
print(chunk);
});
child.stderr.on('data',(chunk)=>{
print(chunk);
});
is entered at either of the places indicated by //A or //B, the behavior changes - the first entered character forces the program to go into the background:
$ node test.js
[1]+ Stopped node test.js
$ a
Typing [DEL] and 'fg' will bring the program back to the foreground. However, it appears that the raw mode has been automatically turned off. The input is only sent after a newline, and Ctrl-C triggers the default SIGINT handler rather than the 'data' event.
Why is program forced into the background and how can it be prevented?
- Note1: The
.bashrcfile passed as a command line arg to spawn contains only the content
PS1='$ '
- Note2: The
{stdio:['pipe','pipe','pipe']}option passed to spawn means that the parent process' stdin, stdout, and stderr are independent of those of the child process. - Note3: Tested in node versions 10LTS and 12LTS
Changing the spawn options from
{
stdio:['pipe','pipe','pipe']
}
to
{
stdio:['pipe','pipe','pipe'],
detached:true
}
solved one problem but created another. Now the following output appears on the stderr of the child process:
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
even though the child subsequently continues to behave like a terminal, as desired.
Now the question is How to get rid of the unnecessary output on stderr of the child process? Of course it can be read and filtered from a users eyes, but there is no guarantee it will always be the same. It would be best if it just wasn't there.
It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.
It seems there has been no activity on this issue for a while, and it is being closed. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.