Skip to content

Commit ca04881

Browse files
authored
update run docs (#2263)
1 parent ff1c478 commit ca04881

1 file changed

Lines changed: 63 additions & 3 deletions

File tree

‎book/scripts.md‎

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,17 @@ str uppercase
250250
# => helloNushell
251251
```
252252

253+
A script like this has no parameters, so `run` ignores any arguments after the script name.
254+
253255
If the script defines `main`, `run` calls it with the pipeline input and with any arguments given after the script name:
254256

255257
```nu
256258
# prefix.nu
257-
def main [--prefix: string = ">"] {
258-
each {|line| $"($prefix) ($line)" }
259+
def main [--prefix(-p): string = ">", --upper(-u)] {
260+
each {|line|
261+
let line = if $upper { $line | str uppercase } else { $line }
262+
$"($prefix) ($line)"
263+
}
259264
}
260265
```
261266

@@ -267,14 +272,69 @@ def main [--prefix: string = ">"] {
267272
# => ╰───┴───────╯
268273
```
269274

270-
The script runs in its own scope, so environment changes it makes (such as setting `$env.FOO` or calling `cd`) don't carry over to the caller.
275+
### Arguments to `main`
276+
277+
`run` matches the arguments after the script name to the parameters of `main`, the same way a call to `main` does. A flag can take its value after `=`, short flags can be combined, and a record spread sets flags by name. Each of these calls returns the same table:
278+
279+
```nu
280+
[a b] | run prefix.nu -u --prefix=">>>"
281+
[a b] | run prefix.nu -up ">>>"
282+
[a b] | run prefix.nu ...{upper: true, prefix: ">>>"}
283+
# => ╭───┬───────╮
284+
# => │ 0 │ >>> A │
285+
# => │ 1 │ >>> B │
286+
# => ╰───┴───────╯
287+
```
288+
289+
An argument that `main` doesn't accept is an error. That includes an unknown flag, an extra positional argument, a flag missing its value, and a value of the wrong type.
290+
291+
Running a script with `nu` converts each argument to the type of its parameter, as described in [Argument Type Interpretation](#argument-type-interpretation). `run` doesn't. Nushell parses the arguments before it reads the script, so a bare `23` is an `int` even where `main` expects a `string`. Quote the value to pass a string:
292+
293+
```nu
294+
[a b] | run prefix.nu --prefix 23
295+
# => Error: nu::shell::cant_convert
296+
# =>
297+
# => × Can't convert to string.
298+
# => ╭─[repl_entry #1:1:32]
299+
# => 1 │ [a b] | run prefix.nu --prefix 23
300+
# => · ─┬
301+
# => · ╰── can't convert int to string
302+
# => ╰────
303+
# => help: `run` doesn't convert script arguments; quote the value to pass a
304+
# => string
305+
306+
[a b] | run prefix.nu --prefix "23"
307+
# => ╭───┬──────╮
308+
# => │ 0 │ 23 a │
309+
# => │ 1 │ 23 b │
310+
# => ╰───┴──────╯
311+
```
312+
313+
`run`'s own flags, such as `--full-reparse`, go before the script name. Everything after the script name belongs to `main`. So `run prefix.nu -f` passes `-f` to `main`, which has no such flag, and `run prefix.nu --help` shows the help for `main` instead of the help for `run`.
314+
315+
To pass a value that starts with `-` as a positional argument, put `--` in front of it, as described in [Arguments Starting with a Dash](#arguments-starting-with-a-dash):
316+
317+
```nu
318+
run greet.nu --upper -- -alice
319+
# => -ALICE
320+
```
321+
322+
A list spread such as `...$args` fills the rest parameter of `main`. Its items stay values even when they look like flags, so a list containing `--upper` can't turn on `--upper`. To set flags from a variable, spread a record instead.
323+
324+
`run` only calls `main`, never one of its [subcommands](#subcommands). With `myscript.nu` from that section, `nu myscript.nu build` calls `main build`, but `run myscript.nu build` passes `build` to `main`. That `main` takes no arguments, so the call fails with an extra positional argument error.
325+
326+
### Scope and Reloading
327+
328+
The script runs in its own scope, so environment changes it makes (such as setting `$env.FOO` or calling `cd`) don't carry over to the caller. While it runs, `$env.CURRENT_FILE` holds the full path of the script and `$env.FILE_PWD` holds its directory.
271329

272330
Like `source`, `run` is a parser keyword: the file name must be a constant, and the file is looked up in the current directory and then in `$NU_LIB_DIRS`. The script is parsed together with the code that calls it. If the script can change after that, for example when a loop calls it again each time you save the file, use `--full-reparse` (`-f`) to reload and reparse it on every call:
273331

274332
```nu
275333
for _ in (watch . --glob=*.nu) { run --full-reparse ./test.nu }
276334
```
277335

336+
If the file name is `null`, `run` does nothing and passes its input on unchanged.
337+
278338
## Shebangs (`#!`)
279339

280340
On Linux and macOS you can optionally use a [shebang](<https://en.wikipedia.org/wiki/Shebang_(Unix)>) to tell the OS that a file should be interpreted by Nu. For example, with the following in a file named `myscript`:

0 commit comments

Comments
 (0)