execa icon indicating copy to clipboard operation
execa copied to clipboard

After 10 echo commands, the process appears to be blocked

Open I-Want-ToBelieve opened this issue 3 years ago • 7 comments

It's very easy to reproduce the problem

const execa = require('execa')
const p = execa('powershell.exe', [
  '-NoLogo',
  '-NoExit',
  '-NoProfile',
  '-ExecutionPolicy',
  'ByPass',
])
p.stdout.pipe(process.stdout)
let i = 0
setInterval(() => {
  p.stdin.write(`echo ${i++}\n`)
}, 100)

If you replace PowerShell with CMD, it can last up to 15 times😅

const execa = require('execa')
const p = execa('cmd.exe')
p.stdout.pipe(process.stdout)
let i = 0
setInterval(() => {
  p.stdin.write(`echo ${i++}\n`)
}, 100)

Maybe I did something wrong?

I-Want-ToBelieve avatar Aug 18 '20 10:08 I-Want-ToBelieve

With the stdio option added, it works as expected, But I still don't know why...

const execa = require('execa')
const p = execa(
  'powershell.exe',
  [
    '-NoLogo',
    '-NoExit',
    '-NoProfile',
    '-ExecutionPolicy',
    'ByPass',
  ],
+  { stdio: ['pipe', 'inherit', 'pipe'] }
)

let i = 0
setInterval(() => {
  p.stdin.write(`echo ${i++}\n`)
}, 100)

I-Want-ToBelieve avatar Aug 18 '20 13:08 I-Want-ToBelieve

I ran more tests to try to find out why

Work as expected:

const EOL = require('os').EOL
const spawn = require('child_process').spawn

const p = spawn(
  'powershell.exe',
  ['-NoLogo', '-NoExit', '-NoProfile', '-ExecutionPolicy', 'ByPass'],
  { stdio: ['pipe', 'pipe', 'pipe'] }
)

const arr = []

p.stdout.on('data', data => void arr.push(data.toString()))

let i = 0
const id = setInterval(() => {
  p.stdin.write(`echo ${i++}${EOL}`)
}, 100)

setTimeout(() => {
  clearInterval(id)
  p.kill()
  console.log(arr)
}, 3e3)

Not working as expected:

const EOL = require('os').EOL
const execa = require('execa')

const p = execa(
  'powershell.exe',
  ['-NoLogo', '-NoExit', '-NoProfile', '-ExecutionPolicy', 'ByPass'],
  { stdio: ['pipe', 'pipe', 'pipe'] }
)

const arr = []

p.stdout.on('data', data => void arr.push(data.toString()))

let i = 0
const id = setInterval(() => {
  p.stdin.write(`echo ${i++}${EOL}`)
}, 100)

setTimeout(() => {
  clearInterval(id)
  p.kill()
  console.log(arr)
}, 3e3)

Work as expected:

const EOL = require('os').EOL
const execa = require('execa')
const fs = require('fs')

const out = fs.openSync('./out.log', 'a')

const p = execa(
  'powershell.exe',
  ['-NoLogo', '-NoExit', '-NoProfile', '-ExecutionPolicy', 'ByPass'],
  { stdio: ['pipe', out, 'pipe'] }
)

let i = 0
const id = setInterval(() => {
  p.stdin.write(`echo ${i++}${EOL}`)
}, 100)
setTimeout(() => {
  clearInterval(id)
  p.kill()
}, 3e3)

Work as expected:

const spawn = require('child_process').spawn
const p = spawn(
  'powershell.exe',
  ['-NoLogo', '-NoExit', '-NoProfile', '-ExecutionPolicy', 'ByPass'],
  { stdio: ['pipe', 'pipe', 'pipe'] }
)
p.stdout.pipe(process.stdout)
let i = 0
setInterval(() => {
  p.stdin.write(`echo ${i++}\n`)
}, 100)

Not working as expected:

const execa = require('execa')
const p = execa(
  'powershell.exe',
  ['-NoLogo', '-NoExit', '-NoProfile', '-ExecutionPolicy', 'ByPass'],
  { stdio: ['pipe', 'pipe', 'pipe'] }
)
p.stdout.pipe(process.stdout)
let i = 0
setInterval(() => {
  p.stdin.write(`echo ${i++}\n`)
}, 100)

I-Want-ToBelieve avatar Aug 18 '20 15:08 I-Want-ToBelieve

Hi @doublethinkio,

Could you try adding the windowsHide: false option and see if this fixes your problem? Thanks!

ehmicky avatar Aug 18 '20 15:08 ehmicky

Hi @ehmicky I just tried it and it doesn't fix the problem

image

As the picture shows, it seems to stop there forever, in the expectation that it will go on and on

I-Want-ToBelieve avatar Aug 18 '20 16:08 I-Want-ToBelieve

If I execute them 20 times in sync, they will work as expected

Work as expected:

const execa = require('execa')
const p = execa(
  'powershell.exe',
  ['-NoLogo', '-NoExit', '-NoProfile', '-ExecutionPolicy', 'ByPass'],
  { stdio: ['pipe', 'pipe', 'pipe'] }
)
p.stdout.pipe(process.stdout)
let i = 0
while (i < 20) {
  p.stdin.write(`echo ${i++}\n`)
}

image

It seems to be an event loop related problem.

I-Want-ToBelieve avatar Aug 18 '20 16:08 I-Want-ToBelieve

This seems to happen for me aswell on Debian when running yarn with execa.

fivethreeo avatar Feb 05 '21 00:02 fivethreeo

Hello, We have the same issue on mac os, did you find a solution ? Thank you

fhenri42 avatar Oct 05 '21 10:10 fhenri42