Home Explore Blog CI



nushell

4th chunk of `book/pipelines.md`
d0609e50b09a6bb6665810a91d1c2b4eda776b23738a95400000000100001103
Currently, the use of `$in` on a stream in a pipeline results in a "collected" value, meaning the pipeline "waits" on the stream to complete before handling `$in` with the full results. However, this behavior is not guaranteed in future releases. To ensure that a stream is collected into a single variable, use the [`collect` command](/commands/docs/collect.html).

Likewise, avoid using `$in` when normal pipeline input will suffice, as internally `$in` forces a conversion from `PipelineData` to `Value` and _may_ result in decreased performance and/or increased memory usage.

## Working with External Commands

Nu commands communicate with each other using the Nu data types (see [types of data](types_of_data.md)), but what about commands outside of Nu? Let's look at some examples of working with external commands:

`internal_command | external_command`

Data will flow from the internal_command to the external_command. This data will get converted to a string, so that they can be sent to the `stdin` of the external_command.

`external_command | internal_command`

Data coming from an external command into Nu will come in as bytes that Nushell will try to automatically convert to UTF-8 text. If successful, a stream of text data will be sent to internal_command. If unsuccessful, a stream of binary data will be sent to internal command. Commands like [`lines`](/commands/docs/lines.md) help make it easier to bring in data from external commands, as it gives discrete lines of data to work with.

`external_command_1 | external_command_2`

Nu works with data piped between two external commands in the same way as other shells, like Bash would. The `stdout` of external_command_1 is connected to the `stdin` of external_command_2. This lets data flow naturally between the two commands.

### Command Input and Output Types

The Basics section above describes how commands can be combined in pipelines as input, filters, or output.
How you can use commands depends on what they offer in terms of input/output handling.

You can check what a command supports with [`help <command name>`](/commands/docs/help.md), which shows the relevant *Input/output types*.

For example, through `help first` we can see that the [`first` command](/commands/docs/first.md) supports multiple input and output types:

```nu
help first
# => […]
# => Input/output types:
# =>   ╭───┬───────────┬────────╮
# =>   │ # │   input   │ output │
# =>   ├───┼───────────┼────────┤
# =>   │ 0 │ list<any> │ any    │
# =>   │ 1 │ binary    │ binary │
# =>   │ 2 │ range     │ any    │
# =>   ╰───┴───────────┴────────╯

[a b c] | first                                                                                                                                   took 1ms
# => a

1..4 | first                                                                                                                                     took 21ms
# => 1
```

As another example, the [`ls` command](/commands/docs/ls.md) supports output but not input:

```nu
help ls
# => […]
# => Input/output types:
# =>   ╭───┬─────────┬────────╮
# =>   │ # │  input  │ output │
# =>   ├───┼─────────┼────────┤
# =>   │ 0 │ nothing │ table  │
# =>   ╰───┴─────────┴────────╯
```

This means, for example, that attempting to pipe into `ls` (`echo .. | ls`) leads to unintended results.
The input stream is ignored, and `ls` defaults to listing the current directory.

To integrate a command like `ls` into a pipeline, you have to explicitly reference the input and pass it as a parameter:

```nu
echo .. | ls $in
```

Note that this only works if `$in` matches the argument type. For example, `[dir1 dir2] | ls $in` will fail with the error `can't convert list<string> to string`.

Other commands without default behavior may fail in different ways, and with explicit errors.

For example, `help sleep` tells us that [`sleep`](/commands/docs/sleep.md) supports no input and no output types:

```nu
help sleep
# => […]
# => Input/output types:

Title: Nu and External Commands: Data Handling, Input/Output Types, and Integration
Summary
This section describes how Nu interacts with external commands, including data conversion between Nu types and strings for 'stdin'. It explains how data is handled when piping between external and internal commands, and between two external commands. Furthermore, it details how to check the input/output types of commands using `help` and how to integrate commands like `ls` into pipelines by explicitly referencing input parameters.