mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 09:25:38 +02:00
Stdout/Stderr redirection (#7185)
This adds new pipeline connectors called out> and err> which redirect either stdout or stderr to a file. You can also use out+err> (or err+out>) to redirect both streams into a file.
This commit is contained in:
@ -2,38 +2,50 @@ use std::ops::{Index, IndexMut};
|
||||
|
||||
use crate::{ast::Expression, engine::StateWorkingSet, Span, VarId};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Redirection {
|
||||
Stdout,
|
||||
Stderr,
|
||||
StdoutAndStderr,
|
||||
}
|
||||
|
||||
// Note: Span in the below is for the span of the connector not the whole element
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PipelineElement {
|
||||
Expression(Expression),
|
||||
Redirect(Expression),
|
||||
And(Expression),
|
||||
Or(Expression),
|
||||
Expression(Option<Span>, Expression),
|
||||
Redirection(Span, Redirection, Expression),
|
||||
And(Span, Expression),
|
||||
Or(Span, Expression),
|
||||
}
|
||||
|
||||
impl PipelineElement {
|
||||
pub fn span(&self) -> Span {
|
||||
match self {
|
||||
PipelineElement::Expression(expression)
|
||||
| PipelineElement::Redirect(expression)
|
||||
| PipelineElement::And(expression)
|
||||
| PipelineElement::Or(expression) => expression.span,
|
||||
PipelineElement::Expression(None, expression) => expression.span,
|
||||
PipelineElement::Expression(Some(span), expression)
|
||||
| PipelineElement::Redirection(span, _, expression)
|
||||
| PipelineElement::And(span, expression)
|
||||
| PipelineElement::Or(span, expression) => Span {
|
||||
start: span.start,
|
||||
end: expression.span.end,
|
||||
},
|
||||
}
|
||||
}
|
||||
pub fn has_in_variable(&self, working_set: &StateWorkingSet) -> bool {
|
||||
match self {
|
||||
PipelineElement::Expression(expression)
|
||||
| PipelineElement::Redirect(expression)
|
||||
| PipelineElement::And(expression)
|
||||
| PipelineElement::Or(expression) => expression.has_in_variable(working_set),
|
||||
PipelineElement::Expression(_, expression)
|
||||
| PipelineElement::Redirection(_, _, expression)
|
||||
| PipelineElement::And(_, expression)
|
||||
| PipelineElement::Or(_, expression) => expression.has_in_variable(working_set),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_in_variable(&mut self, working_set: &mut StateWorkingSet, new_var_id: VarId) {
|
||||
match self {
|
||||
PipelineElement::Expression(expression)
|
||||
| PipelineElement::Redirect(expression)
|
||||
| PipelineElement::And(expression)
|
||||
| PipelineElement::Or(expression) => {
|
||||
PipelineElement::Expression(_, expression)
|
||||
| PipelineElement::Redirection(_, _, expression)
|
||||
| PipelineElement::And(_, expression)
|
||||
| PipelineElement::Or(_, expression) => {
|
||||
expression.replace_in_variable(working_set, new_var_id)
|
||||
}
|
||||
}
|
||||
@ -46,10 +58,10 @@ impl PipelineElement {
|
||||
new_span: Span,
|
||||
) {
|
||||
match self {
|
||||
PipelineElement::Expression(expression)
|
||||
| PipelineElement::Redirect(expression)
|
||||
| PipelineElement::And(expression)
|
||||
| PipelineElement::Or(expression) => {
|
||||
PipelineElement::Expression(_, expression)
|
||||
| PipelineElement::Redirection(_, _, expression)
|
||||
| PipelineElement::And(_, expression)
|
||||
| PipelineElement::Or(_, expression) => {
|
||||
expression.replace_span(working_set, replaced, new_span)
|
||||
}
|
||||
}
|
||||
@ -76,7 +88,10 @@ impl Pipeline {
|
||||
Self {
|
||||
elements: expressions
|
||||
.into_iter()
|
||||
.map(PipelineElement::Expression)
|
||||
.enumerate()
|
||||
.map(|(idx, x)| {
|
||||
PipelineElement::Expression(if idx == 0 { None } else { Some(x.span) }, x)
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,20 @@ impl RawStream {
|
||||
|
||||
Ok(Spanned { item: output, span })
|
||||
}
|
||||
|
||||
pub fn chain(self, stream: RawStream) -> RawStream {
|
||||
RawStream {
|
||||
stream: Box::new(self.stream.chain(stream.stream)),
|
||||
leftover: self
|
||||
.leftover
|
||||
.into_iter()
|
||||
.chain(stream.leftover.into_iter())
|
||||
.collect(),
|
||||
ctrlc: self.ctrlc,
|
||||
is_binary: self.is_binary,
|
||||
span: self.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Debug for RawStream {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
|
Reference in New Issue
Block a user