mirror of
https://github.com/nushell/nushell.git
synced 2025-07-02 07:31:39 +02:00
Support redirect stderr and stdout+stderr with a pipe (#11708)
# Description Close: #9673 Close: #8277 Close: #10944 This pr introduces the following syntax: 1. `e>|`, pipe stderr to next command. Example: `$env.FOO=bar nu --testbin echo_env_stderr FOO e>| str length` 2. `o+e>|` and `e+o>|`, pipe both stdout and stderr to next command, example: `$env.FOO=bar nu --testbin echo_env_mixed out-err FOO FOO e+o>| str length` Note: it only works for external commands. ~There is no different for internal commands, that is, the following three commands do the same things:~ Edit: it raises errors if we want to pipes for internal commands ``` ❯ ls e>| str length Error: × `e>|` only works with external streams ╭─[entry #1:1:1] 1 │ ls e>| str length · ─┬─ · ╰── `e>|` only works on external streams ╰──── ❯ ls e+o>| str length Error: × `o+e>|` only works with external streams ╭─[entry #2:1:1] 1 │ ls e+o>| str length · ──┬── · ╰── `o+e>|` only works on external streams ╰──── ``` This can help us to avoid some strange issues like the following: `$env.FOO=bar (nu --testbin echo_env_stderr FOO) e>| str length` Which is hard to understand and hard to explain to users. # User-Facing Changes Nan # Tests + Formatting To be done # After Submitting Maybe update documentation about these syntax.
This commit is contained in:
@ -68,6 +68,8 @@ impl Block {
|
||||
if let Some(last) = last.elements.last() {
|
||||
match last {
|
||||
PipelineElement::Expression(_, expr) => expr.ty.clone(),
|
||||
PipelineElement::ErrPipedExpression(_, expr) => expr.ty.clone(),
|
||||
PipelineElement::OutErrPipedExpression(_, expr) => expr.ty.clone(),
|
||||
PipelineElement::Redirection(_, _, _, _) => Type::Any,
|
||||
PipelineElement::SeparateRedirection { .. } => Type::Any,
|
||||
PipelineElement::SameTargetRedirection { .. } => Type::Any,
|
||||
|
@ -13,6 +13,8 @@ pub enum Redirection {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum PipelineElement {
|
||||
Expression(Option<Span>, Expression),
|
||||
ErrPipedExpression(Option<Span>, Expression),
|
||||
OutErrPipedExpression(Option<Span>, Expression),
|
||||
// final field indicates if it's in append mode
|
||||
Redirection(Span, Redirection, Expression, bool),
|
||||
// final bool field indicates if it's in append mode
|
||||
@ -32,7 +34,9 @@ pub enum PipelineElement {
|
||||
impl PipelineElement {
|
||||
pub fn expression(&self) -> &Expression {
|
||||
match self {
|
||||
PipelineElement::Expression(_, expression) => expression,
|
||||
PipelineElement::Expression(_, expression)
|
||||
| PipelineElement::ErrPipedExpression(_, expression)
|
||||
| PipelineElement::OutErrPipedExpression(_, expression) => expression,
|
||||
PipelineElement::Redirection(_, _, expression, _) => expression,
|
||||
PipelineElement::SeparateRedirection {
|
||||
out: (_, expression, _),
|
||||
@ -50,11 +54,15 @@ impl PipelineElement {
|
||||
pub fn span(&self) -> Span {
|
||||
match self {
|
||||
PipelineElement::Expression(None, expression)
|
||||
| PipelineElement::ErrPipedExpression(None, expression)
|
||||
| PipelineElement::OutErrPipedExpression(None, expression)
|
||||
| PipelineElement::SameTargetRedirection {
|
||||
cmd: (None, expression),
|
||||
..
|
||||
} => expression.span,
|
||||
PipelineElement::Expression(Some(span), expression)
|
||||
| PipelineElement::ErrPipedExpression(Some(span), expression)
|
||||
| PipelineElement::OutErrPipedExpression(Some(span), expression)
|
||||
| PipelineElement::Redirection(span, _, expression, _)
|
||||
| PipelineElement::SeparateRedirection {
|
||||
out: (span, expression, _),
|
||||
@ -74,6 +82,8 @@ impl PipelineElement {
|
||||
pub fn has_in_variable(&self, working_set: &StateWorkingSet) -> bool {
|
||||
match self {
|
||||
PipelineElement::Expression(_, expression)
|
||||
| PipelineElement::ErrPipedExpression(_, expression)
|
||||
| PipelineElement::OutErrPipedExpression(_, expression)
|
||||
| PipelineElement::Redirection(_, _, expression, _)
|
||||
| PipelineElement::And(_, expression)
|
||||
| PipelineElement::Or(_, expression)
|
||||
@ -96,6 +106,8 @@ impl PipelineElement {
|
||||
) {
|
||||
match self {
|
||||
PipelineElement::Expression(_, expression)
|
||||
| PipelineElement::ErrPipedExpression(_, expression)
|
||||
| PipelineElement::OutErrPipedExpression(_, expression)
|
||||
| PipelineElement::Redirection(_, _, expression, _)
|
||||
| PipelineElement::And(_, expression)
|
||||
| PipelineElement::Or(_, expression)
|
||||
|
Reference in New Issue
Block a user