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

Permit combining stdout/stderr as streams to external command behind pipe #9673

Closed
x10an14 opened this issue Jul 13, 2023 · 15 comments · Fixed by #11708
Closed

Permit combining stdout/stderr as streams to external command behind pipe #9673

x10an14 opened this issue Jul 13, 2023 · 15 comments · Fixed by #11708
Labels
enhancement New feature or request redirection-pipe All related to redirection to files or more complex pipelines with STDERR streaming Issues related to streaming data (or collecting data when it should be streamed)
Milestone

Comments

@x10an14
Copy link

x10an14 commented Jul 13, 2023

Question

Given command foo, which outputs both stdout and stderr, how can I pipe both of stdout and stderr from foo into bar through a pipe?

Ref these (non-exhaustive list of) alternatives which achieve this in bash:

foo |& bar
foo 2>&1 | bar

Additional context and details

The only way for me to automate checking of my flake.nix checks (in a nice graphical output) in Nushell when using nom now is this arcane invocation:

bash -c 'nix flake check --log-format internal-json -vv |& nom --json'

Feels weird that I cannot do the equivalent of "combine outputs and redirect them through pipe" in Nushell =S

@x10an14 x10an14 added the question the issue author asks something label Jul 13, 2023
@fdncred
Copy link
Collaborator

fdncred commented Jul 13, 2023

You could try the complete command but it won't interleave stderr and stdout.

❯ do { ^ls } | complete
╭───────────┬─────────────────────╮
│ stdout    │ CODE_OF_CONDUCT.md  │
│           │ CONTRIBUTING.md     │
│           │ Cargo.lock          │
│           │ Cargo.toml          │
│           │ Cross.toml          │
│ stderr    │                     │
│ exit_code │ 0                   │
╰───────────┴─────────────────────╯

@hardfau1t
Copy link
Contributor

You could try the complete command but it won't interleave stderr and stdout.

  • it won't work for stream data, data will be availabe once the program exits

@x10an14 x10an14 changed the title How can I redirect stdout and stderr (combined) as stdin through a pipe? How can I redirect stdout and stderr (combined as a stream) as stdin through a pipe? Jul 14, 2023
@x10an14
Copy link
Author

x10an14 commented Jul 14, 2023

You could try the complete command but it won't interleave stderr and stdout.

  • it won't work for stream data, data will be availabe once the program exits

Thank you for the clarification! The intent behind the example given is to receive streamed data to get a nice visualization of the progress =)

@x10an14
Copy link
Author

x10an14 commented Jul 14, 2023

Considering the replies received so far, should this become a feature request instead?

@hardfau1t
Copy link
Contributor

Considering the replies received so far, should this become a feature request instead?

IMO it should be, AFAIK there is no straight way to do this(not sure whether it is possible or not) and it is most common in unix systems

@amtoine
Copy link
Member

amtoine commented Jul 14, 2023

@x10an14
you can just update the title and the body of this issue to make it a feature request 😉

@x10an14 x10an14 changed the title How can I redirect stdout and stderr (combined as a stream) as stdin through a pipe? Permit combining stdout/stderr as streams to external command behind pipe Jul 14, 2023
@x10an14
Copy link
Author

x10an14 commented Jul 14, 2023

@amtoine: @x10an14 you can just update the title and the body of this issue to make it a feature request 😉

Will you replace the question label/add the feature flag label? =)

@fdncred fdncred added enhancement New feature or request and removed question the issue author asks something labels Jul 15, 2023
@fdncred
Copy link
Collaborator

fdncred commented Jul 15, 2023

done

@amtoine
Copy link
Member

amtoine commented Jul 15, 2023

thanks @x10an14 😊

@sholderbach sholderbach added streaming Issues related to streaming data (or collecting data when it should be streamed) redirection-pipe All related to redirection to files or more complex pipelines with STDERR labels Jul 18, 2023
@Spickelbing
Copy link

I had the same problem just now and went with run-external --redirect-combine foo | bar. But a shorter way to do this would help.

@x10an14
Copy link
Author

x10an14 commented Aug 14, 2023

I had the same problem just now and went with run-external --redirect-combine foo | bar. But a shorter way to do this would help.

Can you link/reference/document the redirect-combine flag? And never heard of it or it's command. I have yet to check if it's a built-in

@fdncred
Copy link
Collaborator

fdncred commented Aug 14, 2023

https://www.nushell.sh/commands/docs/run-external.html

I think this is the PR where it was added in April.
#8918

@x10an14
Copy link
Author

x10an14 commented Aug 16, 2023

The run-external --redirect-combine tip works! But only if I quote each and every word starting with a hyphen (read: flag) like so (it seems):

run-external --redirect-combine nix flake check "--log-format" internal-json "-v" | nom --json

While this is of course much better than my previous "use bash" solution, would run-external (by its intent and nature) not be better suited to pass all inputs starting with - to the command its encompassing/running?

Dunno how, but force ordering of flags for run-external to come before the wrapped command maybe?

@x10an14
Copy link
Author

x10an14 commented Aug 16, 2023

This is how it looks like if I don't quoute all flags sent to wrapped binary/command:

2023-08-16 17:18:03+02:00: ~/Doc/sr./nix-configs via ❄️  impure (nix-shell-env)
x10an14@nav-840G8-laptop ❯ > run-external --redirect-combine nix flake check "--log-format" internal-json -v | nom --json
Error: nu::parser::unknown_flag

  × The `run-external` command doesn't have flag `-v`.
   ╭─[entry #3:1:1]
 1 │ run-external --redirect-combine nix flake check "--log-format" internal-json -v | nom --json
   ·                                                                               ┬
   ·                                                                               ╰── unknown flag
   ╰────
  help: Available flags: --help(-h), --redirect-stdout, --redirect-stderr, --redirect-combine, --trim-end-newline.
        Use `--help` for more information.

@CAD97
Copy link
Contributor

CAD97 commented Oct 23, 2023

A helper to prevent run-external from trying to interpret your command's flags:

def --wrapped run [cmd ...args] { run-external --redirect-combine $cmd $args }

For the convenience you give up the ability to control the flags given to run-external, but get an experience much closer to how ^ works. Each flag you define on run can't be passed through without quoting, but using the wrapper limits that to exclusively just the automatic --help(-h) switch.

A more principled solution would be to teach Nu how to use -- to delineate the end of flags and that all following args are rest arguments. The best solution would probably be to be able to combine "retroactively" and do something like ^external | combine like you can do ^external | complete.

WindSoilder added a commit that referenced this issue Feb 8, 2024
# 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.
@hustcer hustcer added this to the v0.91.0 milestone Feb 9, 2024
dmatos2012 pushed a commit to dmatos2012/nushell that referenced this issue Feb 20, 2024
# Description
Close: nushell#9673
Close: nushell#8277
Close: nushell#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 nushell#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 nushell#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request redirection-pipe All related to redirection to files or more complex pipelines with STDERR streaming Issues related to streaming data (or collecting data when it should be streamed)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants