mirror of
https://github.com/nushell/nushell.git
synced 2025-08-14 17:58:37 +02:00
Fix external redirect (#3345)
* Fix external redirection * Fix external redirection
This commit is contained in:
@ -4,7 +4,8 @@ use crate::evaluation_context::EvaluationContext;
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::ParserScope;
|
||||
use nu_protocol::hir::{
|
||||
Block, Call, ClassifiedCommand, Expression, Pipeline, SpannedExpression, Synthetic,
|
||||
Block, Call, ClassifiedCommand, Expression, ExternalRedirection, Pipeline, SpannedExpression,
|
||||
Synthetic,
|
||||
};
|
||||
use nu_protocol::{UntaggedValue, Value};
|
||||
use nu_source::{Span, Tag};
|
||||
@ -15,13 +16,15 @@ pub fn run_block(
|
||||
block: &Block,
|
||||
ctx: &EvaluationContext,
|
||||
mut input: InputStream,
|
||||
external_redirection: ExternalRedirection,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let mut output: Result<InputStream, ShellError> = Ok(OutputStream::empty());
|
||||
for (_, definition) in block.definitions.iter() {
|
||||
ctx.scope.add_definition(definition.clone());
|
||||
}
|
||||
|
||||
for group in &block.block {
|
||||
let num_groups = block.block.len();
|
||||
for (group_num, group) in block.block.iter().enumerate() {
|
||||
match output {
|
||||
Ok(inp) if inp.is_empty() => {}
|
||||
Ok(inp) => {
|
||||
@ -75,7 +78,9 @@ pub fn run_block(
|
||||
}
|
||||
}
|
||||
output = Ok(OutputStream::empty());
|
||||
for pipeline in &group.pipelines {
|
||||
|
||||
let num_pipelines = group.pipelines.len();
|
||||
for (pipeline_num, pipeline) in group.pipelines.iter().enumerate() {
|
||||
match output {
|
||||
Ok(inp) if inp.is_empty() => {}
|
||||
Ok(mut output_stream) => {
|
||||
@ -112,7 +117,13 @@ pub fn run_block(
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
output = run_pipeline(pipeline, ctx, input);
|
||||
output = if group_num == (num_groups - 1) && pipeline_num == (num_pipelines - 1) {
|
||||
// we're at the end of the block, so use the given external redirection
|
||||
run_pipeline(pipeline, ctx, input, external_redirection)
|
||||
} else {
|
||||
// otherwise, we're in the middle of the block, so use a default redirection
|
||||
run_pipeline(pipeline, ctx, input, ExternalRedirection::Stdout)
|
||||
};
|
||||
|
||||
input = OutputStream::empty();
|
||||
}
|
||||
@ -125,13 +136,15 @@ fn run_pipeline(
|
||||
commands: &Pipeline,
|
||||
ctx: &EvaluationContext,
|
||||
mut input: InputStream,
|
||||
external_redirection: ExternalRedirection,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
for item in commands.list.clone() {
|
||||
input = match item {
|
||||
let num_commands = commands.list.len();
|
||||
for (command_num, command) in commands.list.iter().enumerate() {
|
||||
input = match command {
|
||||
ClassifiedCommand::Dynamic(call) => {
|
||||
let mut args = vec![];
|
||||
if let Some(positional) = call.positional {
|
||||
for pos in &positional {
|
||||
if let Some(positional) = &call.positional {
|
||||
for pos in positional {
|
||||
let result = run_expression_block(pos, ctx)?.into_vec();
|
||||
args.push(result);
|
||||
}
|
||||
@ -160,7 +173,8 @@ fn run_pipeline(
|
||||
{
|
||||
ctx.scope.add_var(param.0.name(), value[0].clone());
|
||||
}
|
||||
let result = run_block(&captured_block.block, ctx, input);
|
||||
let result =
|
||||
run_block(&captured_block.block, ctx, input, external_redirection);
|
||||
ctx.scope.exit_scope();
|
||||
|
||||
let result = result?;
|
||||
@ -174,9 +188,17 @@ fn run_pipeline(
|
||||
|
||||
ClassifiedCommand::Expr(expr) => run_expression_block(&*expr, ctx)?,
|
||||
|
||||
ClassifiedCommand::Error(err) => return Err(err.into()),
|
||||
ClassifiedCommand::Error(err) => return Err(err.clone().into()),
|
||||
|
||||
ClassifiedCommand::Internal(left) => run_internal_command(left, ctx, input)?,
|
||||
ClassifiedCommand::Internal(left) => {
|
||||
if command_num == (num_commands - 1) {
|
||||
let mut left = left.clone();
|
||||
left.args.external_redirection = external_redirection;
|
||||
run_internal_command(&left, ctx, input)?
|
||||
} else {
|
||||
run_internal_command(left, ctx, input)?
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ fn evaluate_invocation(block: &hir::Block, ctx: &EvaluationContext) -> Result<Va
|
||||
None => InputStream::empty(),
|
||||
};
|
||||
|
||||
let result = run_block(&block, ctx, input)?;
|
||||
let result = run_block(&block, ctx, input, hir::ExternalRedirection::Stdout)?;
|
||||
|
||||
let output = result.into_vec();
|
||||
|
||||
|
@ -13,7 +13,7 @@ use nu_source::{PrettyDebug, Span, Tag};
|
||||
use nu_stream::{ActionStream, InputStream};
|
||||
|
||||
pub(crate) fn run_internal_command(
|
||||
command: InternalCommand,
|
||||
command: &InternalCommand,
|
||||
context: &EvaluationContext,
|
||||
input: InputStream,
|
||||
) -> Result<InputStream, ShellError> {
|
||||
@ -30,7 +30,7 @@ pub(crate) fn run_internal_command(
|
||||
let result = context.run_command(
|
||||
internal_command,
|
||||
Tag::unknown_anchor(command.name_span),
|
||||
command.args,
|
||||
command.args.clone(), // FIXME: this is inefficient
|
||||
objects,
|
||||
)?;
|
||||
Ok(InputStream::from_stream(InternalIteratorSimple {
|
||||
|
@ -2,8 +2,8 @@ use crate::{maybe_print_errors, path::canonicalize, run_block};
|
||||
use crate::{BufCodecReader, MaybeTextCodec, StringOrBinary};
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::{
|
||||
Call, ClassifiedCommand, Expression, InternalCommand, Literal, NamedArguments,
|
||||
SpannedExpression,
|
||||
Call, ClassifiedCommand, Expression, ExternalRedirection, InternalCommand, Literal,
|
||||
NamedArguments, SpannedExpression,
|
||||
};
|
||||
use nu_protocol::{Primitive, UntaggedValue, Value};
|
||||
use nu_stream::{InputStream, ToInputStream};
|
||||
@ -185,7 +185,7 @@ pub fn process_script(
|
||||
|
||||
trace!("{:#?}", block);
|
||||
|
||||
let result = run_block(&block, ctx, input_stream);
|
||||
let result = run_block(&block, ctx, input_stream, ExternalRedirection::None);
|
||||
|
||||
match result {
|
||||
Ok(input) => {
|
||||
|
@ -77,11 +77,9 @@ impl WholeStreamCommand for Arc<Block> {
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let call_info = args.call_info.clone();
|
||||
|
||||
let mut block = self.clone();
|
||||
let block = self.clone();
|
||||
|
||||
if let Some(block) = std::sync::Arc::<nu_protocol::hir::Block>::get_mut(&mut block) {
|
||||
block.set_redirect(call_info.args.external_redirection);
|
||||
}
|
||||
let external_redirection = args.call_info.args.external_redirection;
|
||||
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let evaluated = call_info.evaluate(&ctx)?;
|
||||
@ -178,7 +176,7 @@ impl WholeStreamCommand for Arc<Block> {
|
||||
}
|
||||
}
|
||||
}
|
||||
let result = run_block(&block, &ctx, input);
|
||||
let result = run_block(&block, &ctx, input, external_redirection);
|
||||
ctx.scope.exit_scope();
|
||||
result
|
||||
}
|
||||
|
Reference in New Issue
Block a user