diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 336f345c5a..d0ce1ab9d9 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -169,12 +169,13 @@ impl ExternalCommand { if let Ok(input) = input { for value in input.into_iter() { - if let Value::String { val, span: _ } = value { - if stdin_write.write(val.as_bytes()).is_err() { - return Ok(()); - } - } else { - return Err(()); + let buf = match value { + Value::String { val, .. } => val.into_bytes(), + Value::Binary { val, .. } => val, + _ => return Err(()), + }; + if stdin_write.write(&buf).is_err() { + return Ok(()); } } } diff --git a/src/main.rs b/src/main.rs index d61c723208..63b56412cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -159,6 +159,8 @@ fn main() -> Result<()> { "echo_env" => test_bins::echo_env(), "cococo" => test_bins::cococo(), "meow" => test_bins::meow(), + "meowb" => test_bins::meowb(), + "relay" => test_bins::relay(), "iecho" => test_bins::iecho(), "fail" => test_bins::fail(), "nonu" => test_bins::nonu(), diff --git a/src/test_bins.rs b/src/test_bins.rs index a6b8f9b839..bdd0ac4d43 100644 --- a/src/test_bins.rs +++ b/src/test_bins.rs @@ -34,6 +34,25 @@ pub fn meow() { } } +// A binary version of meow +pub fn meowb() { + let args: Vec = args(); + + let stdout = io::stdout(); + let mut handle = stdout.lock(); + + for arg in args.iter().skip(1) { + let buf = std::fs::read(arg).expect("Expected a filepath"); + handle.write_all(&buf).expect("failed to write to stdout"); + } +} + +// Relays anything received on stdin to stdout +pub fn relay() { + io::copy(&mut io::stdin().lock(), &mut io::stdout().lock()) + .expect("failed to copy stdin to stdout"); +} + pub fn nonu() { args().iter().skip(1).for_each(|arg| print!("{}", arg)); } diff --git a/tests/shell/pipeline/commands/external.rs b/tests/shell/pipeline/commands/external.rs index 6bb1baf677..2951af4589 100644 --- a/tests/shell/pipeline/commands/external.rs +++ b/tests/shell/pipeline/commands/external.rs @@ -97,6 +97,16 @@ fn redirects_custom_command_external() { assert_eq!(actual.out, "8"); } +#[test] +fn passes_binary_data_between_externals() { + let actual = nu!(cwd: "tests/fixtures/formats", r#"nu --testbin meowb sample.db | nu --testbin relay | hash sha256"#); + + assert_eq!( + actual.out, + "2f5050e7eea415c1f3d80b5d93355efd15043ec9157a2bb167a9e73f2ae651f2" + ) +} + mod it_evaluation { use super::nu; use nu_test_support::fs::Stub::{EmptyFile, FileWithContent, FileWithContentToBeTrimmed};