zx icon indicating copy to clipboard operation
zx copied to clipboard

An easy way to specify stdin

Open neongreen opened this issue 1 year ago • 1 comments

Right now, there are (at least?) two ways to specify stdin:

  1. Via pipes:

    $`echo ${input} | command`

    This works, but at least on GitHub runners it can suffer from random SIGPIPE (exit code 141) failures that are not reproducible locally. No idea why.

  2. Via .stdin:

    const p = $`command`
    p.stdin.write(input)
    p.stdin.end()
    

    This requires giving a name to the command itself, and is a bit cumbersome to use.

I propose pushing the latter pattern into a function or a method, eg. something like

$`command`.input(input)

or perhaps

function withInput(cmd: zx.ProcessPromise, input: string): zx.ProcessPromise {
  cmd.stdin.write(input)
  cmd.stdin.end()
  return cmd
}

neongreen avatar Feb 03 '24 11:02 neongreen

Nice idea

antonmedv avatar Feb 03 '24 16:02 antonmedv

Not quite familiar with zx or js, but I have played a bit with both as well as other languages. I think this is a good idea, and could cut down on cumbersome-ness.

XDuskAshes avatar Mar 04 '24 17:03 XDuskAshes

$command.input(input)

We're planning to introduce smth like $(opts)`cmd args` in the netx major release, and the input option is definitely adopted.

const input = '{"name": "foo"}'
const name = await $({input})`jq -r .name` // foo

const stdin = fs.createReadStream(path.join(fixtures, 'foo.json'))
const data = await $({stdin})`jq -r .data` // foo

const p = $`echo "5\\n3\\n1\\n4\\n2"`
const sorted = $({input: p})`sort` // 1\n2\n3\n4\n5

antongolub avatar Mar 04 '24 18:03 antongolub