yarnpkg / berry

πŸ“¦πŸˆ Active development trunk for Yarn βš’
https://yarnpkg.com
BSD 2-Clause "Simplified" License
7.44k stars 1.11k forks source link

[Bug?]: Combining redirections (>&) does not work #4033

Open jeffrson opened 2 years ago

jeffrson commented 2 years ago

Self-service

Describe the bug

@yarnpkg/shell supports redirection of stdout and stderr: "command > stdout.txt 2> stderr.txt"

Apparently, combining those into one stream is also implemented. However, it does not work as intended. Given this "command > stdout.txt 2>&1" it should be expected, that both standard output and standard error are written to stdout.txt. However, standard error is not redirected, but written to "real" standard out of process. A bit of a mess...

To reproduce

// I'm sorry - it's not really sherlock - don't know how to demonstrate shell redirection

import {PassThrough} from 'stream'

import {execute} from '@yarnpkg/shell'

const stdout = new PassThrough()
const stderr = new PassThrough()

const stdoutChunks = []
const stderrChunks = []

stdout.on(`data`, chunk => stdoutChunks.push(chunk))
stderr.on(`data`, chunk => stderrChunks.push(chunk))

const command = 'node -e "console.log(\\"stdout\\"); console.error(\\"stderr\\")" > out1 2>&1'

execute(command, [], {stdout, stderr})
.then((exitCode => {
  const output = Buffer.concat(stdoutChunks).toString()
  const error = Buffer.concat(stderrChunks).toString()

  console.log('out: ' + output) // output should be empty, but isn't - contains "stderr"
  console.log('err: ' + error)  // error should be empty and is
}))

Environment

System:
    OS: Linux 5.10 Debian GNU/Linux 11 (bullseye) 11 (bullseye)
    CPU: (16) x64 Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
  Binaries:
    Node: 16.13.2 - /tmp/xfs-e70720b2/node
    Yarn: 3.1.1 - /tmp/xfs-e70720b2/yarn
    npm: 6.14.16 - ~/.nvm/versions/node/v16.13.2/bin/npm

Additional context

No response

yarnbot commented 2 years ago

Hi! πŸ‘‹

This issue looks stale, and doesn't feature the reproducible label - which implies that you didn't provide a working reproduction using Sherlock. As a result, it'll be closed in a few days unless a maintainer explicitly vouches for it or you edit your first post to include a formal reproduction (you can use the playground for that).

Note that we require Sherlock reproductions for long-lived issues (rather than standalone git repositories or similar) because we're a small team. Sherlock gives us the ability to check which bugs are still affecting the master branch at any given point, and decreases the amount of code we need to run on our own machines (thus leading to faster bug resolutions). It helps us help you! πŸ˜ƒ

If you absolutely cannot reproduce a bug on Sherlock (for example because it's a Windows-only issue), a maintainer will have to manually add the upholded label. Thanks for helping us triaging our repository! 🌟

vegerot commented 3 months ago

I can reproduce this.

Use this package.json

{
  "scripts": {
    "stdout-and-stderr": "(echo out; type stderr) 1>/dev/null 2>&1"
  }
}

Now try running this script with different package runners:

$ npm run stdout-and-stderr

> PageBank@1.0.0 stdout-and-stderr
> (echo out; type stderr) 1>/dev/null 2>&1

$ bun run stdout-and-stderr
$ (echo out; type stderr) 1>/dev/null 2>&1
error: script "stdout-and-stderr" exited with code 1

$ deno task stdout-and-stderr
Task stdout-and-stderr (echo out; type stderr) 1>/dev/null 2>&1
error: Error parsing script 'stdout-and-stderr'.

Caused by:
    Multiple redirects are currently not supported.
      1>/dev/null 2>&1
      ~

$ yarn stdout-and-stderr
/usr/bin/type: line 4: type: stderr: not found

You can see that yarn does not respect the 2>&1. However, if I change the script to

    "stdout-and-stderr": "(echo out; type stderr) 1>/dev/null 2>/dev/null"

It works correctly

$ yarn stdout-and-stderr