Nushell
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
  • 한국어
GitHub
  • Introduction
  • Installation
    • Default Shell
  • Getting Started
    • Quick Tour
    • Moving Around the System
    • Thinking in Nu
    • Nushell Cheat Sheet
  • Nu Fundamentals
    • Types of Data
    • Loading Data
    • Pipelines
    • Working with Strings
    • Working with Lists
    • Working with Records
    • Working with Tables
    • Navigating and Accessing Structured Data
    • Special Variables
  • Programming in Nu
    • Custom Commands
    • Aliases
    • Operators
    • Variables
    • Control Flow
    • Scripts
    • Modules
      • Using Modules
      • Creating Modules
    • Overlays
    • Sorting
    • Testing your Nushell Code
    • Best Practices
  • Nu as a Shell
    • Configuration
    • Environment
    • Stdout, Stderr, and Exit Codes
    • Running System (External) Commands
    • How to Configure 3rd Party Prompts
    • Directory Stack
    • Reedline, Nu's Line Editor
    • Custom Completions
    • Externs
    • Coloring and Theming in Nu
    • Hooks
    • Background Jobs
  • Coming to Nu
    • Coming from Bash
    • Coming from CMD.EXE
    • Coming from PowerShell
    • Nu map from other shells and domain specific languages
    • Nu Map from Imperative Languages
    • Nu Map from Functional Languages
    • Nushell operator map
  • Design Notes
    • How Nushell Code Gets Run
  • (Not So) Advanced
    • Standard Library
    • Dataframes
    • Metadata
    • Creating Your Own Errors
    • Parallelism
    • Plugins
    • explore
    • Building TUIs with tui

Environment

A common task in a shell is to control the environment that external applications will use. This is often done automatically, as the environment is packaged up and given to the external application as it launches. Sometimes, though, we want to have more precise control over what environment variables an application sees.

You can see the current environment variables in the $env variable:

$env | table -e
# => ╭──────────────────────┬───────────────────────────────────────────────────────────────────────────╮
# => │ ENV_CONVERSIONS      │ {record 0 fields}                                                         │
# => │ HOME                 │ /Users/jelle                                                              │
# => │ LSCOLORS             │ GxFxCxDxBxegedabagaced                                                    │
# => │                      │ ╭───┬──────────────────────────────────────────────────────────────╮      │
# => │ NU_LIB_DIRS          │ │ 0 │ /Users/jelle/Library/Application Support/nushell/scripts     │      │
# => │                      │ │ 1 │ /Users/jelle/Library/Application Support/nushell/completions │      │
# => │                      │ ╰───┴──────────────────────────────────────────────────────────────╯      │
# => │ NU_PLUGIN_DIRS       │ [list 0 items]                                                            │
# => │ NU_VERSION           │ 0.116.0                                                                   │
# => │                      │ ╭───┬──────────╮                                                          │
# => │ PATH                 │ │ 0 │ /usr/bin │                                                          │
# => │                      │ │ 1 │ /bin     │                                                          │
# => │                      │ ╰───┴──────────╯                                                          │
# => │ ...                  │ ...                                                                       │
# => ╰──────────────────────┴───────────────────────────────────────────────────────────────────────────╯

In Nushell, environment variables can be any value and have any type. You can see the type of an env variable with the describe command, for example: $env.PROMPT_COMMAND | describe.

To send environment variables to external applications, the values will need to be converted to strings. See Environment variable conversions on how this works.

The environment is initially created from the Nu configuration files and from the environment that Nu is run inside of.

Setting Environment Variables

There are several ways to set an environment variable:

$env.VAR assignment

Using the $env.VAR = "val" is the most straightforward method

$env.FOO = 'BAR'

So, if you want to extend the PATH variable, for example, you could do that as follows.

$env.PATH = ($env.PATH | prepend '/path/you/want/to/add')
# or, with a Windows path:
# $env.PATH = ($env.PATH | prepend 'C:\path\you\want\to\add')

Here we've prepended our folder to the existing folders in the path, so it will have the highest priority. If you want to give it the lowest priority instead, you can use the append command.

load-env

If you have more than one environment variable you'd like to set, you can use load-env to create a table of name/value pairs and load multiple variables at the same time:

load-env { "BOB": "FOO", "JAY": "BAR" }

One-shot Environment Variables

These are defined to be active only temporarily for a duration of executing a code block. See Single-use environment variables for details.

Calling a Command Defined with def --env

See Defining environment from custom commands for details.

Using Module's Exports

See Modules for details.

Reading Environment Variables

Individual environment variables are fields of a record that is stored in the $env variable and can be read with $env.VARIABLE:

$env.FOO
# => BAR

Sometimes, you may want to access an environmental variable which might be unset. Consider using the optional operator to avoid an error:

$env.NOT_SET | describe
# => Error: nu::shell::column_not_found
# =>
# =>   × Cannot find column 'NOT_SET'
# =>    ╭─[repl_entry #1:1:1]
# =>  1 │ $env.NOT_SET | describe
# =>    · ──────┬─────┬
# =>    ·       │     ╰── value originates here
# =>    ·       ╰── column 'NOT_SET' is missing in one or more values
# =>    ╰────
# =>   help: If some rows have this column, try using 'NOT_SET?' for optional access, or pre-fill using the `default` command

$env.NOT_SET? | describe
# => nothing

$env.NOT_SET? | default "BAR"
# => BAR

Alternatively, you can check for the presence of an environmental variable with in:

$env.FOO
# => BAR

if "FOO" in $env {
    echo $env.FOO
}
# => BAR

Case sensitivity

Nushell's $env is case-insensitive, regardless of the OS. Although $env behaves mostly like a record, it is special in that it ignores the case when reading or updating. This means, for example, you can use any of $env.PATH, $env.Path, or $env.path, and they all work the same on any OS:

$env.FOO = 'BAR'
$env.foo
# => BAR

This only applies when you access $env directly with a cell path, like $env.foo. When $env is used as a value, such as when it is piped into a command or used with the in operator, it is a regular record with case-sensitive keys. So if you want to read $env in a case-sensitive manner, use $env | get FOO ($env | get foo is an error) or "FOO" in $env.

Scoping

When you set an environment variable inside a closure or a custom command (unless the command is defined with def --env), it will be available only in that scope (the closure or command and any block inside of it).

Here is a small example to demonstrate the environment scoping:

$env.FOO = "BAR"
do {
    $env.FOO = "BAZ"
    $env.FOO == "BAZ"
}
# => true
$env.FOO == "BAR"
# => true

The blocks of control flow keywords such as if, for, while, loop, and match are not closures, so environment changes made inside them remain after the block ends:

if true { $env.FOO = "BAZ" }
$env.FOO
# => BAZ

See also: Changing the Environment in a Custom Command.

Changing the Directory

A common task in a shell is to change the directory using the cd command. In Nushell, calling cd is equivalent to setting the PWD environment variable. Therefore, it follows the same rules as other environment variables (for example, scoping).

Single-use Environment Variables

A common shorthand to set an environment variable once is available, inspired by Bash and others:

FOO=BAR $env.FOO
# => BAR

You can also use with-env to do the same thing more explicitly:

with-env { FOO: BAR } { $env.FOO }
# => BAR

The with-env command will temporarily set the environment variable to the value given (here: the variable "FOO" is given the value "BAR"). Once this is done, the block will run with this new environment variable set.

Permanent Environment Variables

You can also set environment variables at startup so they are available for the duration of Nushell running. To do this, set an environment variable inside the Nu configuration file.

For example:

# In config.nu
$env.FOO = 'BAR'

Environment Variable Conversions

You can set the ENV_CONVERSIONS environment variable to convert other environment variables between a string and a value. Nushell itself converts the PATH (and Path used on Windows) environment variable from a string to a list when it starts, before any configuration file is loaded, so it does not need an entry in ENV_CONVERSIONS (which is an empty record by default). When you assign $env.ENV_CONVERSIONS, any existing string environment variable specified inside it is immediately translated according to its from_string field into a value of any type. External tools require environment variables to be strings, therefore, any non-string environment variable needs to be converted first. The conversion of value -> string is set by the to_string field of ENV_CONVERSIONS and is done every time an external command is run.

Let's illustrate the conversions with an example. Put the following in your config.nu:

$env.ENV_CONVERSIONS = {
    FOO : {
        from_string: { |s| $s | split row '-' }
        to_string: { |v| $v | str join '-' }
    }
}

Now, when Nushell starts with FOO set to 'a-b-c' in its environment (for example, when you run with-env { FOO: 'a-b-c' } { nu }), config.nu assigns $env.ENV_CONVERSIONS, which converts FOO into a list in the new instance.

Because the conversion happens whenever $env.ENV_CONVERSIONS is assigned, you can also try it in your current session:

$env.FOO = 'a-b-c'
$env.ENV_CONVERSIONS = $env.ENV_CONVERSIONS  # re-apply the conversions to the existing variables
$env.FOO
# => ╭───┬───╮
# => │ 0 │ a │
# => │ 1 │ b │
# => │ 2 │ c │
# => ╰───┴───╯

You can see the $env.FOO is now a list. You can also test the conversion manually by

do $env.ENV_CONVERSIONS.FOO.from_string 'a-b-c'
# => ╭───┬───╮
# => │ 0 │ a │
# => │ 1 │ b │
# => │ 2 │ c │
# => ╰───┴───╯

Now, to test the conversion list -> string, run:

nu -c '$env.FOO'
# => a-b-c

Because nu is an external program, Nushell translated the [ a b c ] list according to ENV_CONVERSIONS.FOO.to_string and passed it to the nu process. Running commands with nu -c does not load the config file, therefore the env conversion for FOO is missing and it is displayed as a plain string -- this way we can verify the translation was successful. You can also run this step manually by do $env.ENV_CONVERSIONS.FOO.to_string [a b c]

(Important! The string -> value conversion happens only for variables that already exist when $env.ENV_CONVERSIONS is assigned, such as those inherited from the parent process. A variable that you set as a string afterwards stays a string. To convert it, set it before assigning ENV_CONVERSIONS, or assign $env.ENV_CONVERSIONS to itself again.)

Removing Environment Variables

You can remove an environment variable with hide-env:

$env.FOO = 'BAR'
hide-env FOO

The hiding is also scoped which both allows you to remove an environment variable temporarily and prevents you from modifying a parent environment from within a child scope:

$env.FOO = 'BAR'
do {
  hide-env FOO
  # $env.FOO does not exist
}
$env.FOO
# => BAR
Edit this page on GitHub
Contributors: Carson Black, Ibraheem Ahmed, Jonathan Turner, Michael Angerman, JT, prrao87, Hristo Filaretov, Jakub Žádník, jntrnr, stormasm, Reilly Wood, Justin Ma, chtenb, fdncred, Jonas Gollenz, amtoine, AntoineStevan, Zhora Trush, Dan Davison, Leon, Hofer-Julian, Máté FARKAS, Stefan Holderbach, Mate Farkas, Jelle Besseling, WindSoilder, petrisch, 132ikl, arnau, Ian Manske, YizhePKU, NotTheDr01ds, 0x4D5352, joshuanussbaum, Jan Klass, hank20010209
Prev
Configuration
Next
Stdout, Stderr, and Exit Codes