Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redirect: support redirect stderr with piping stdout to next commands. #10851

Merged
merged 42 commits into from
Nov 23, 2023

Conversation

WindSoilder
Copy link
Collaborator

@WindSoilder WindSoilder commented Oct 27, 2023

Description

Fixes: #10271

Given the following script:

# test.sh
echo aaaaa
echo bbbbb 1>&2
echo cc

This pr makes the following command possible:

bash test.sh err> /dev/null | lines | each {|line| $line | str length}

General idea behind the change:

When nushell redirect stderr message to external file

  1. it take stdout of external stream, and pass this stream to next command, so it won't block next pipeline command from running.
  2. relative stderr stream are handled by save command

These two streams are handled separately, so we need to delegate a thread to save command, or else we'll have a chance to hang nushell, we have meet a similar before: #5625.

One case to consider

What if we're failed to save to an external stream? (Like we don't have a permission to save to a file)?
In this case nushell will just print a waning message, and don't stop the following scripts from running.

User-Facing Changes

Before

 bash test2.sh err> /dev/null | lines | each {|line| $line | str length}
aaaaa
cc

After

 bash test2.sh err> /dev/null | lines | each {|line| $line | str length}
╭───┬───╮
 0  5 
 1  2 
╰───┴───╯

BTY, after this pr, the following commands are impossible either, it's important to make sure that the implementation doesn't introduce too much costs:

 echo a e> a.txt e> a.txt
Error:   × Can't make stderr redirection twice
   ╭─[entry #1:1:1]
 1 │ echo a e> a.txt e> a.txt
   ·                 ─┬
   ·                  ╰── try to remove one
   ╰────

❯ echo a o> a.txt o> a.txt
Error:   × Can't make stdout redirection twice
   ╭─[entry #2:1:1]
 1  echo a o> a.txt o> a.txt
   ·                 ─┬
   ·                  ╰── try to remove one
   ╰────

@101313
Copy link

101313 commented Oct 28, 2023

This has troubled me a lot, thanks man bless you

@WindSoilder
Copy link
Collaborator Author

WindSoilder commented Nov 3, 2023

I have no idea how to fix the CI....The CI runs failed because we save stderr in another thread, but we don't know if the thread is finished. The machine is too busy to run this child thread


Edit: finally I come up a way to make CI green :-D

@WindSoilder WindSoilder marked this pull request as ready for review November 8, 2023 23:29
Copy link
Member

@sholderbach sholderbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for figuring this out and testing it!

I think we should move towards landing it soon :)

@@ -288,3 +288,38 @@ fn redirection_should_have_a_target() {
);
}
}

#[test]
#[cfg(not(windows))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great if we could convert this test to something that reliably runs on all platforms.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking a way to make such output in our testbin.
I'd prefer to make it in separate pr, cause it requires a lot of changes in tests

crates/nu-engine/src/eval.rs Outdated Show resolved Hide resolved
@WindSoilder WindSoilder merged commit 57808ca into nushell:main Nov 23, 2023
19 checks passed
hardfau1t pushed a commit to hardfau1t/nushell that referenced this pull request Dec 14, 2023
nushell#10851)

# Description
Fixes: nushell#10271

Given the following script:
```shell
# test.sh
echo aaaaa
echo bbbbb 1>&2
echo cc
```

This pr makes the following command possible:
```nushell
bash test.sh err> /dev/null | lines | each {|line| $line | str length}
```


## General idea behind the change:
When nushell redirect stderr message to external file
1. it take stdout of external stream, and pass this stream to next
command, so it won't block next pipeline command from running.
2. relative stderr stream are handled by `save` command

These two streams are handled separately, so we need to delegate a
thread to `save` command, or else we'll have a chance to hang nushell,
we have meet a similar before: nushell#5625.

### One case to consider
What if we're failed to save to an external stream? (Like we don't have
a permission to save to a file)?
In this case nushell will just print a waning message, and don't stop
the following scripts from running.

# User-Facing Changes
## Before
```nushell
❯ bash test2.sh err> /dev/null | lines | each {|line| $line | str length}
aaaaa
cc
```

## After
```nushell
❯ bash test2.sh err> /dev/null | lines | each {|line| $line | str length}
╭───┬───╮
│ 0 │ 5 │
│ 1 │ 2 │
╰───┴───╯
```

BTY, after this pr, the following commands are impossible either, it's
important to make sure that the implementation doesn't introduce too
much costs:
```nushell
❯ echo a e> a.txt e> a.txt
Error:   × Can't make stderr redirection twice
   ╭─[entry #1:1:1]
 1 │ echo a e> a.txt e> a.txt
   ·                 ─┬
   ·                  ╰── try to remove one
   ╰────

❯ echo a o> a.txt o> a.txt
Error:   × Can't make stdout redirection twice
   ╭─[entry nushell#2:1:1]
 1 │ echo a o> a.txt o> a.txt
   ·                 ─┬
   ·                  ╰── try to remove one
   ╰────
```
dmatos2012 pushed a commit to dmatos2012/nushell that referenced this pull request Feb 20, 2024
nushell#10851)

# Description
Fixes: nushell#10271

Given the following script:
```shell
# test.sh
echo aaaaa
echo bbbbb 1>&2
echo cc
```

This pr makes the following command possible:
```nushell
bash test.sh err> /dev/null | lines | each {|line| $line | str length}
```


## General idea behind the change:
When nushell redirect stderr message to external file
1. it take stdout of external stream, and pass this stream to next
command, so it won't block next pipeline command from running.
2. relative stderr stream are handled by `save` command

These two streams are handled separately, so we need to delegate a
thread to `save` command, or else we'll have a chance to hang nushell,
we have meet a similar before: nushell#5625.

### One case to consider
What if we're failed to save to an external stream? (Like we don't have
a permission to save to a file)?
In this case nushell will just print a waning message, and don't stop
the following scripts from running.

# User-Facing Changes
## Before
```nushell
❯ bash test2.sh err> /dev/null | lines | each {|line| $line | str length}
aaaaa
cc
```

## After
```nushell
❯ bash test2.sh err> /dev/null | lines | each {|line| $line | str length}
╭───┬───╮
│ 0 │ 5 │
│ 1 │ 2 │
╰───┴───╯
```

BTY, after this pr, the following commands are impossible either, it's
important to make sure that the implementation doesn't introduce too
much costs:
```nushell
❯ echo a e> a.txt e> a.txt
Error:   × Can't make stderr redirection twice
   ╭─[entry nushell#1:1:1]
 1 │ echo a e> a.txt e> a.txt
   ·                 ─┬
   ·                  ╰── try to remove one
   ╰────

❯ echo a o> a.txt o> a.txt
Error:   × Can't make stdout redirection twice
   ╭─[entry nushell#2:1:1]
 1 │ echo a o> a.txt o> a.txt
   ·                 ─┬
   ·                  ╰── try to remove one
   ╰────
```
@WindSoilder WindSoilder deleted the redirect branch February 27, 2024 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

How to redirect stderr but continue to pipe stdout?
4 participants