├── .envrc ├── .gitignore ├── tests ├── single.env ├── empty.env ├── simple.env ├── error.env ├── shell-variables.env ├── Ming's menu of (merciless) monstrosities.env └── shell-functions.env ├── LICENSE ├── bash-env.nu ├── extra-module-tests.nu ├── .github └── workflows │ └── test-suite.yml ├── flake.nix ├── tests.nu ├── flake.lock ├── README.plugin.md └── README.md /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.direnv/ 2 | /result 3 | -------------------------------------------------------------------------------- /tests/single.env: -------------------------------------------------------------------------------- 1 | export MISSION=Impossible 2 | -------------------------------------------------------------------------------- /tests/empty.env: -------------------------------------------------------------------------------- 1 | # move along, nothing to see here 2 | -------------------------------------------------------------------------------- /tests/simple.env: -------------------------------------------------------------------------------- 1 | export A=a 2 | export B=b 3 | unset C 4 | -------------------------------------------------------------------------------- /tests/error.env: -------------------------------------------------------------------------------- 1 | export A=a 2 | export B=b 3 | 4 | @oops 5 | -------------------------------------------------------------------------------- /tests/shell-variables.env: -------------------------------------------------------------------------------- 1 | A="not exported" 2 | export B="exported" 3 | -------------------------------------------------------------------------------- /tests/Ming's menu of (merciless) monstrosities.env: -------------------------------------------------------------------------------- 1 | export SPACEMAN="One small step for a man ..." 2 | export QUOTE="\"Well done!\" is better than \"Well said!\"" 3 | export MIXED_BAG="Did the sixth sheik's sixth sheep say \"baa\", or not?" 4 | -------------------------------------------------------------------------------- /tests/shell-functions.env: -------------------------------------------------------------------------------- 1 | export A=1 2 | export B=1 3 | 4 | function f2() { 5 | export A=2 6 | export B=2 7 | C2="I am shell variable C2" 8 | } 9 | 10 | function f3() { 11 | export A=3 12 | export B=3 13 | C3="I am shell variable C3" 14 | } 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2023-2024 Simon Guest 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /bash-env.nu: -------------------------------------------------------------------------------- 1 | export def main [ 2 | path?: string 3 | --export: list 4 | --shellvars (-s) 5 | --fn (-f): list 6 | ] { 7 | let fn_args = if ($fn | is-not-empty) { 8 | ['--shellfns' ($fn | str join ',')] 9 | } else { 10 | [] 11 | } 12 | 13 | let path_args = if $path != null { 14 | [($path | path expand)] 15 | } else { 16 | [] 17 | } 18 | 19 | let input_str = $in | default "" | str join "\n" 20 | let raw = $input_str | bash-env-json ...($fn_args ++ $path_args) | complete 21 | let raw_json = $raw.stdout | from json 22 | 23 | let error = $raw_json | get -o error 24 | if $error != null { 25 | error make { msg: $error } 26 | } else if $raw.exit_code != 0 { 27 | error make { msg: $"unexpected failure from bash-env-json ($raw.stderr)" } 28 | } 29 | 30 | if ($export | is-not-empty) { 31 | print "warning: --export is deprecated, use --shellvars(-s) instead" 32 | let exported_shellvars = ($raw_json.shellvars | select -o ...$export) 33 | $raw_json.env | merge ($exported_shellvars) 34 | } else if $shellvars or ($fn | is-not-empty) { 35 | $raw_json 36 | } else { 37 | $raw_json.env 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /extra-module-tests.nu: -------------------------------------------------------------------------------- 1 | use std assert 2 | 3 | # TODO use testing.nu testing module, 4 | # which wasn't working at the time I wrote these tests 5 | 6 | #[test] 7 | def test_shell_variables [] { 8 | let actual = (echo "A=123" | bash-env -s).shellvars 9 | let expected = { A: "123" } 10 | assert equal $actual $expected 11 | } 12 | 13 | #[test] 14 | def test_shell_variables_from_file [] { 15 | let actual = bash-env -s tests/shell-variables.env | reject meta 16 | let expected = { shellvars: { A: "not exported" } env: { B: "exported" } } 17 | assert equal $actual $expected 18 | } 19 | 20 | #[test] 21 | def test_shell_functions [] { 22 | let actual = bash-env -f [f2 f3] tests/shell-functions.env | reject meta 23 | let expected = { 24 | "env": { 25 | "B": "1", 26 | "A": "1" 27 | }, 28 | "shellvars": {}, 29 | "fn": { 30 | "f2": { 31 | "env": { 32 | "B": "2", 33 | "A": "2" 34 | }, 35 | "shellvars": { 36 | "C2": "I am shell variable C2" 37 | } 38 | }, 39 | "f3": { 40 | "env": { 41 | "B": "3", 42 | "A": "3" 43 | }, 44 | "shellvars": { 45 | "C3": "I am shell variable C3" 46 | } 47 | } 48 | } 49 | } 50 | assert equal $actual $expected 51 | } 52 | 53 | export def main [] { 54 | test_shell_variables 55 | test_shell_variables_from_file 56 | test_shell_functions 57 | 58 | print "All tests passed" 59 | } 60 | -------------------------------------------------------------------------------- /.github/workflows/test-suite.yml: -------------------------------------------------------------------------------- 1 | name: test suite 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | env: 10 | NU_VERSION: 0.106.0 11 | BASH_ENV_JSON_VERSION: 0.10.1 12 | 13 | jobs: 14 | test: 15 | name: Test 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v4 20 | - name: Download Nushell $NU_VERSION 21 | run: | 22 | curl -L https://github.com/nushell/nushell/releases/download/${NU_VERSION}/nu-${NU_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar xzf - 23 | - name: Version Check 24 | run: | 25 | export PATH=./nu-${NU_VERSION}-x86_64-unknown-linux-gnu:$PATH 26 | nu --version 27 | bash --version 28 | jq --version 29 | - name: Download bash-env-json $BASH_ENV_JSON_VERSION 30 | run: | 31 | curl -L https://github.com/tesujimath/bash-env-json/archive/refs/tags/${BASH_ENV_JSON_VERSION}.tar.gz | tar xzf - 32 | - name: Run Module Tests 33 | run: | 34 | # note that Nushell doesn't like relative paths on the $PATH 35 | export PATH=$(pwd)/bash-env-json-${BASH_ENV_JSON_VERSION}:./nu-${NU_VERSION}-x86_64-unknown-linux-gnu:$PATH 36 | which bash-env-json 37 | nu --no-config-file --no-history -c "use bash-env.nu ; use tests.nu run_bash_env_tests ; run_bash_env_tests" 38 | nu --no-config-file --no-history -c "use bash-env.nu ; use extra-module-tests.nu ; extra-module-tests" 39 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "nu_plugin_bash_env"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 6 | 7 | flake-utils.url = "github:numtide/flake-utils"; 8 | 9 | bash-env-json = { 10 | url = "github:tesujimath/bash-env-json/main"; 11 | inputs.nixpkgs.follows = "nixpkgs"; 12 | }; 13 | }; 14 | 15 | outputs = { nixpkgs, flake-utils, bash-env-json, ... }: 16 | flake-utils.lib.eachDefaultSystem 17 | (system: 18 | let 19 | pkgs = import nixpkgs { 20 | inherit system; 21 | }; 22 | 23 | inherit (pkgs) lib stdenvNoCC; 24 | flakePkgs = { 25 | bash-env-json = bash-env-json.packages.${system}.default; 26 | }; 27 | 28 | bash-env-module-with-bash-env-json = stdenvNoCC.mkDerivation 29 | { 30 | name = "bash-env.nu-with-bash-env-json"; 31 | src = ./bash-env.nu; 32 | dontUnpack = true; 33 | preferLocalBuild = true; 34 | allowSubstitutes = false; 35 | 36 | buildPhase = '' 37 | runHook preBuild 38 | mkdir -p "$out" 39 | substitute "$src" "$out/bash-env.nu" --replace-fail ${lib.escapeShellArg "bash-env-json"} ${lib.escapeShellArg "${flakePkgs.bash-env-json}/bin/bash-env-json"} 40 | runHook postBuild 41 | ''; 42 | }; 43 | in 44 | { 45 | devShells.default = 46 | let 47 | inherit (pkgs) 48 | mkShell 49 | bashInteractive 50 | jq 51 | nushell; 52 | in 53 | 54 | mkShell { 55 | nativeBuildInputs = [ 56 | bashInteractive 57 | jq 58 | nushell 59 | ]; 60 | }; 61 | 62 | packages = { 63 | default = bash-env-module-with-bash-env-json; 64 | module = bash-env-module-with-bash-env-json; 65 | }; 66 | } 67 | ); 68 | } 69 | -------------------------------------------------------------------------------- /tests.nu: -------------------------------------------------------------------------------- 1 | use std assert 2 | 3 | # TODO use testing.nu testing module, 4 | # which wasn't working at the time I wrote these tests 5 | 6 | #[test] 7 | def test_echo [] { 8 | let actual = echo "export A=123" | bash-env 9 | let expected = { A: "123" } 10 | assert equal $actual $expected 11 | } 12 | 13 | #[test] 14 | def test_not_exported [] { 15 | let actual = echo "A=123" | bash-env 16 | let expected = { } 17 | assert equal $actual $expected 18 | } 19 | 20 | #[test] 21 | def test_export_shell_variables [] { 22 | let actual = echo "A=123" | bash-env --export [A] 23 | let expected = { A: "123" } 24 | assert equal $actual $expected 25 | } 26 | 27 | #[test] 28 | def test_shell_variables_from_file [] { 29 | let actual = bash-env tests/shell-variables.env 30 | let expected = { B: "exported" } 31 | assert equal $actual $expected 32 | } 33 | 34 | #[test] 35 | def test_export_shell_variables_from_file [] { 36 | let actual = bash-env --export [A] tests/shell-variables.env 37 | let expected = { A: "not exported" B: "exported" } 38 | assert equal $actual $expected 39 | } 40 | 41 | #[test] 42 | def test_empty_value [] { 43 | let actual = echo "export A=\"\"" | bash-env 44 | let expected = { A: "" } 45 | assert equal $actual $expected 46 | } 47 | 48 | #[test] 49 | def test_simple_file [] { 50 | let actual = bash-env tests/simple.env 51 | let expected = { A: "a" B: "b" } 52 | assert equal $actual $expected 53 | } 54 | 55 | #[test] 56 | def test_cat_simple_file [] { 57 | let actual = cat tests/simple.env | bash-env 58 | let expected = { A: "a" B: "b" } 59 | assert equal $actual $expected 60 | } 61 | 62 | #[test] 63 | def test_nasty_values_from_file [] { 64 | let actual = bash-env "tests/Ming's menu of (merciless) monstrosities.env" 65 | let expected = { 66 | SPACEMAN: "One small step for a man ..." 67 | QUOTE: "\"Well done!\" is better than \"Well said!\"" 68 | MIXED_BAG: "Did the sixth sheik's sixth sheep say \"baa\", or not?" 69 | } 70 | assert equal $actual $expected 71 | } 72 | 73 | export def run_bash_env_tests [] { 74 | test_echo 75 | test_not_exported 76 | test_export_shell_variables 77 | test_shell_variables_from_file 78 | test_export_shell_variables_from_file 79 | test_empty_value 80 | test_simple_file 81 | test_cat_simple_file 82 | test_nasty_values_from_file 83 | 84 | print "All tests passed" 85 | } 86 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "bash-env-json": { 4 | "inputs": { 5 | "flake-utils": "flake-utils", 6 | "nixpkgs": [ 7 | "nixpkgs" 8 | ] 9 | }, 10 | "locked": { 11 | "lastModified": 1735682486, 12 | "narHash": "sha256-IHfUIAkpaRyBmzT654bAzpTHUhcrtU643uxkPbveYOM=", 13 | "owner": "tesujimath", 14 | "repo": "bash-env-json", 15 | "rev": "36bb756f38282e33deeed8e27618ecde3503e032", 16 | "type": "github" 17 | }, 18 | "original": { 19 | "owner": "tesujimath", 20 | "ref": "main", 21 | "repo": "bash-env-json", 22 | "type": "github" 23 | } 24 | }, 25 | "flake-utils": { 26 | "inputs": { 27 | "systems": "systems" 28 | }, 29 | "locked": { 30 | "lastModified": 1726560853, 31 | "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", 32 | "owner": "numtide", 33 | "repo": "flake-utils", 34 | "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", 35 | "type": "github" 36 | }, 37 | "original": { 38 | "owner": "numtide", 39 | "repo": "flake-utils", 40 | "type": "github" 41 | } 42 | }, 43 | "flake-utils_2": { 44 | "inputs": { 45 | "systems": "systems_2" 46 | }, 47 | "locked": { 48 | "lastModified": 1710146030, 49 | "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", 50 | "owner": "numtide", 51 | "repo": "flake-utils", 52 | "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", 53 | "type": "github" 54 | }, 55 | "original": { 56 | "owner": "numtide", 57 | "repo": "flake-utils", 58 | "type": "github" 59 | } 60 | }, 61 | "nixpkgs": { 62 | "locked": { 63 | "lastModified": 1739138025, 64 | "narHash": "sha256-M4ilIfGxzbBZuURokv24aqJTbdjPA9K+DtKUzrJaES4=", 65 | "owner": "NixOS", 66 | "repo": "nixpkgs", 67 | "rev": "b2243f41e860ac85c0b446eadc6930359b294e79", 68 | "type": "github" 69 | }, 70 | "original": { 71 | "owner": "NixOS", 72 | "ref": "nixpkgs-unstable", 73 | "repo": "nixpkgs", 74 | "type": "github" 75 | } 76 | }, 77 | "root": { 78 | "inputs": { 79 | "bash-env-json": "bash-env-json", 80 | "flake-utils": "flake-utils_2", 81 | "nixpkgs": "nixpkgs" 82 | } 83 | }, 84 | "systems": { 85 | "locked": { 86 | "lastModified": 1681028828, 87 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 88 | "owner": "nix-systems", 89 | "repo": "default", 90 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 91 | "type": "github" 92 | }, 93 | "original": { 94 | "owner": "nix-systems", 95 | "repo": "default", 96 | "type": "github" 97 | } 98 | }, 99 | "systems_2": { 100 | "locked": { 101 | "lastModified": 1681028828, 102 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 103 | "owner": "nix-systems", 104 | "repo": "default", 105 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 106 | "type": "github" 107 | }, 108 | "original": { 109 | "owner": "nix-systems", 110 | "repo": "default", 111 | "type": "github" 112 | } 113 | } 114 | }, 115 | "root": "root", 116 | "version": 7 117 | } 118 | -------------------------------------------------------------------------------- /README.plugin.md: -------------------------------------------------------------------------------- 1 | # nu_plugin_bash_env 2 | 3 | Historically Bash environment for Nushell was provided via the `nu_plugin_bash_env` plugin in this repo. 4 | 5 | That plugin has now been removed in favour of the `bash-env` module, which is more feature rich and also embarrassingly simpler than the plugin. 6 | 7 | ## Historical plugin docunentation 8 | 9 | ### Plugin Version Compatability 10 | 11 | Since Nushell 0.91.0 the plugin protocol was enhanced and now requires version compatability between plugins and Nushell itself. 12 | 13 | The following versions are compatible. 14 | 15 | | Nushell | bash-env plugin | 16 | | ------- | --------------- | 17 | | 0.89 | 0.5.0 | 18 | | 0.90 | 0.5.0 | 19 | | 0.91 | 0.6.2 | 20 | | 0.92 | 0.7.1 | 21 | | 0.93 | 0.8.0 | 22 | | 0.93 | 0.9.0 | 23 | | 0.94 | 0.10.0 | 24 | | 0.95 | 0.11.0 | 25 | | 0.96 | 0.12.1 | 26 | | 0.97 | 0.13.0 | 27 | | 0.98 | 0.14.2 | 28 | | 0.98 | 0.15.1 | 29 | | 0.99 | 0.16.1 | 30 | | 0.100 | 0.17.3 | 31 | 32 | Note that the plugin will not work in later versions of Nushell, and will not be updated to fix that. Use the module instead (above). 33 | 34 | ### Dependencies 35 | 36 | The script uses `jq` for output formatting. Previous versions required at least `jq` version `1.7`, but that may be no longer the case. 37 | 38 | Also I suspect at least Bash version `5.1`. 39 | 40 | Since version `0.15.0`, this plugin uses [`bash-env-json`](https://github.com/tesujimath/bash-env-json) instead of the previously bundled `bash_env.sh` script. However, this is fetched and embedded at build time, so there is no difference at runtime. 41 | 42 | ### Examples 43 | 44 | #### Simple Usage 45 | ``` 46 | > bash-env tests/simple.env 47 | ╭───┬───╮ 48 | │ B │ b │ 49 | │ A │ a │ 50 | ╰───┴───╯ 51 | 52 | > echo $env.A 53 | Error: nu::shell::name_not_found 54 | 55 | × Name not found 56 | 57 | 58 | > bash-env tests/simple.env | load-env 59 | 60 | > echo $env.A 61 | a 62 | > echo $env.B 63 | b 64 | 65 | 66 | > bash-env tests/simple.env 67 | ╭──────────────╮ 68 | │ empty record │ 69 | ╰──────────────╯ 70 | 71 | # no new or changed environment variables, so nothing returned 72 | 73 | > ssh-agent | bash-env 74 | Agent pid 98985 75 | ╭───────────────┬───────────────────────────────────╮ 76 | │ SSH_AUTH_SOCK │ /tmp/ssh-XXXXXXFIMT9y/agent.98982 │ 77 | │ SSH_AGENT_PID │ 98985 │ 78 | ╰───────────────┴───────────────────────────────────╯ 79 | ``` 80 | 81 | #### Exporting Shell Variables 82 | 83 | The plugin supports `--export` for exporting shell variables into the environment. 84 | 85 | ``` 86 | > echo "ABC=123" | bash-env 87 | ╭──────────────╮ 88 | │ empty record │ 89 | ╰──────────────╯ 90 | 91 | > echo "export ABC=123" | bash-env 92 | ╭─────┬─────╮ 93 | │ ABC │ 123 │ 94 | ╰─────┴─────╯ 95 | 96 | > echo "ABC=123" | bash-env --export [ABC] 97 | ╭─────┬─────╮ 98 | │ ABC │ 123 │ 99 | ╰─────┴─────╯ 100 | 101 | > bash-env /etc/os-release 102 | ╭──────────────╮ 103 | │ empty record │ 104 | ╰──────────────╯ 105 | 106 | > bash-env --export [ID PRETTY_NAME] /etc/os-release 107 | ╭─────────────┬──────────────────────╮ 108 | │ ID │ nixos │ 109 | │ PRETTY_NAME │ NixOS 24.05 (Uakari) │ 110 | ╰─────────────┴──────────────────────╯ 111 | ``` 112 | 113 | #### Escaping Special Characters 114 | 115 | Care has been taken to escape any special characters. 116 | 117 | ``` 118 | > bash-env `tests/Ming's "menu" of (merciless) monstrosities.env` 119 | ╭───────────┬──────────────────────────────────────────────────────╮ 120 | │ QUOTE │ "Well done!" is better than "Well said!" │ 121 | │ SPACEMAN │ One small step for a man ... │ 122 | │ MIXED_BAG │ Did the sixth sheik's sixth sheep say "baa", or not? │ 123 | ╰───────────┴──────────────────────────────────────────────────────╯ 124 | 125 | > bash-env `tests/Ming's "menu" of (merciless) monstrosities.env` | load-env 126 | > echo $env.QUOTE 127 | "Well done!" is better than "Well said!" 128 | ``` 129 | 130 | ### Implementation 131 | 132 | Prior to 0.13.0 this plugin was written in Bash, with the Nu plugin protocol done by hand using `jq`, with insights from the [api](api) sub-directory which contained a Rust program to produce what is required, using the official Nu plugin library. This was too onerous to maintain through the evolution of the protocol, so was abandoned. 133 | 134 | Since 0.13.0, the plugin is written in Rust, with the much simplified Bash script embedded. 135 | 136 | By default the embedded Bash script is extracted at runtime into a temporary directory. This behaviour may be overridden by setting the ``NU_PLUGIN_BASH_ENV_JSON` environment variable, which is then expected to resolve to the path of the pre-installed script. 137 | 138 | ### Logging 139 | 140 | Logging is supported via the Rust `tracing-subscriber` crate, with log-level defined by the environment variable `NU_PLUGIN_BASH_ENV_LOG`. 141 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bash environment for Nushell 2 | 3 | Historically Bash environment for Nushell was provided via the `nu_plugin_bash_env` plugin in this repo. 4 | 5 | That plugin has now been removed in favour of the `bash-env` module, which is more feature rich and also embarrassingly simpler than the plugin. For historical documentation for the plugin see its [README](README.plugin.md). 6 | 7 | ## bash-env module 8 | 9 | ### Examples 10 | 11 | #### Simple Usage 12 | ``` 13 | > bash-env ./tests/simple.env 14 | ╭───┬───╮ 15 | │ B │ b │ 16 | │ A │ a │ 17 | ╰───┴───╯ 18 | > echo $env.A 19 | Error: nu::shell::column_not_found 20 | 21 | × Cannot find column 'A' 22 | ╭─[entry #77:1:6] 23 | 1 │ echo $env.A 24 | · ───┬──┬ 25 | · │ ╰── value originates here 26 | · ╰── cannot find column 'A' 27 | ╰──── 28 | 29 | > bash-env ./tests/simple.env | load-env 30 | > echo $env.A 31 | a 32 | > echo $env.B 33 | b 34 | 35 | 36 | > bash-env tests/simple.env 37 | ╭──────────────╮ 38 | │ empty record │ 39 | ╰──────────────╯ 40 | 41 | # no new or changed environment variables, so nothing returned 42 | 43 | > ssh-agent | bash-env 44 | ╭───────────────┬─────────────────────────────────────╮ 45 | │ SSH_AUTH_SOCK │ /tmp/ssh-XXXXXXOjZtSh/agent.1612713 │ 46 | │ SSH_AGENT_PID │ 1612715 │ 47 | ╰───────────────┴─────────────────────────────────────╯ 48 | ``` 49 | 50 | #### Shell Variables 51 | 52 | Rather than folding shell variables in with the environment variables as was done by the plugin, the `-s` or `--shellvars` option results in structured output with separate `env` and `shellvars`. 53 | 54 | ``` 55 | > echo "ABC=123" | bash-env 56 | ╭──────────────╮ 57 | │ empty record │ 58 | ╰──────────────╯ 59 | 60 | > echo "ABC=123" | bash-env -s 61 | ╭───────────┬───────────────────╮ 62 | │ env │ {record 0 fields} │ 63 | │ │ ╭─────┬─────╮ │ 64 | │ shellvars │ │ ABC │ 123 │ │ 65 | │ │ ╰─────┴─────╯ │ 66 | ╰───────────┴───────────────────╯ 67 | > (echo "ABC=123" | bash-env -s).shellvars 68 | ╭─────┬─────╮ 69 | │ ABC │ 123 │ 70 | ╰─────┴─────╯ 71 | 72 | > bash-env /etc/os-release 73 | ╭──────────────╮ 74 | │ empty record │ 75 | ╰──────────────╯ 76 | 77 | > (bash-env /etc/os-release -s).shellvars 78 | ╭───────────────────┬─────────────────────────────────────────╮ 79 | │ LOGO │ nix-snowflake │ 80 | │ NAME │ NixOS │ 81 | │ BUG_REPORT_URL │ https://github.com/NixOS/nixpkgs/issues │ 82 | │ HOME_URL │ https://nixos.org/ │ 83 | │ VERSION_CODENAME │ vicuna │ 84 | │ ANSI_COLOR │ 1;34 │ 85 | │ ID │ nixos │ 86 | │ PRETTY_NAME │ NixOS 24.11 (Vicuna) │ 87 | │ DOCUMENTATION_URL │ https://nixos.org/learn.html │ 88 | │ SUPPORT_URL │ https://nixos.org/community.html │ 89 | │ IMAGE_ID │ │ 90 | │ VERSION_ID │ 24.11 │ 91 | │ VERSION │ 24.11 (Vicuna) │ 92 | │ IMAGE_VERSION │ │ 93 | │ BUILD_ID │ 24.11.20240916.99dc878 │ 94 | ╰───────────────────┴─────────────────────────────────────────╯ 95 | ``` 96 | 97 | ### Shell Functions 98 | 99 | Shell functions may be run and their effect on the environment captured. 100 | 101 | ``` 102 | > cat ./tests/shell-functions.env 103 | export A=1 104 | export B=1 105 | 106 | function f2() { 107 | export A=2 108 | export B=2 109 | C2="I am shell variable C2" 110 | } 111 | 112 | function f3() { 113 | export A=3 114 | export B=3 115 | C3="I am shell variable C3" 116 | } 117 | > bash-env ./tests/shell-functions.env 118 | ╭───┬───╮ 119 | │ B │ 1 │ 120 | │ A │ 1 │ 121 | ╰───┴───╯ 122 | > bash-env -f [f2 f3] ./tests/shell-functions.env 123 | ╭───────────┬──────────────────────────────────────────────────────────╮ 124 | │ │ ╭───┬───╮ │ 125 | │ env │ │ B │ 1 │ │ 126 | │ │ │ A │ 1 │ │ 127 | │ │ ╰───┴───╯ │ 128 | │ shellvars │ {record 0 fields} │ 129 | │ │ ╭────┬─────────────────────────────────────────────────╮ │ 130 | │ fn │ │ │ ╭───────────┬─────────────────────────────────╮ │ │ 131 | │ │ │ f2 │ │ │ ╭───┬───╮ │ │ │ 132 | │ │ │ │ │ env │ │ B │ 2 │ │ │ │ 133 | │ │ │ │ │ │ │ A │ 2 │ │ │ │ 134 | │ │ │ │ │ │ ╰───┴───╯ │ │ │ 135 | │ │ │ │ │ │ ╭────┬────────────────────────╮ │ │ │ 136 | │ │ │ │ │ shellvars │ │ C2 │ I am shell variable C2 │ │ │ │ 137 | │ │ │ │ │ │ ╰────┴────────────────────────╯ │ │ │ 138 | │ │ │ │ ╰───────────┴─────────────────────────────────╯ │ │ 139 | │ │ │ │ ╭───────────┬─────────────────────────────────╮ │ │ 140 | │ │ │ f3 │ │ │ ╭───┬───╮ │ │ │ 141 | │ │ │ │ │ env │ │ B │ 3 │ │ │ │ 142 | │ │ │ │ │ │ │ A │ 3 │ │ │ │ 143 | │ │ │ │ │ │ ╰───┴───╯ │ │ │ 144 | │ │ │ │ │ │ ╭────┬────────────────────────╮ │ │ │ 145 | │ │ │ │ │ shellvars │ │ C3 │ I am shell variable C3 │ │ │ │ 146 | │ │ │ │ │ │ ╰────┴────────────────────────╯ │ │ │ 147 | │ │ │ │ ╰───────────┴─────────────────────────────────╯ │ │ 148 | │ │ ╰────┴─────────────────────────────────────────────────╯ │ 149 | ╰───────────┴──────────────────────────────────────────────────────────╯ 150 | 151 | > (bash-env -f [f2 f3] ./tests/shell-functions.env).fn.f2.env 152 | ╭───┬───╮ 153 | │ B │ 2 │ 154 | │ A │ 2 │ 155 | ╰───┴───╯ 156 | > (bash-env -f [f2 f3] ./tests/shell-functions.env).fn.f2.env | load-env 157 | > echo $env.B 158 | 2 159 | 160 | ``` 161 | 162 | ### Installation 163 | 164 | Download the module, and add to `config.nu`: 165 | 166 | ``` 167 | use /path/to/bash-env.nu 168 | ``` 169 | 170 | In contrast to the plugin, the module requires [`bash-env-json`](https://github.com/tesujimath/bash-env-json) to be separately downloaded and installed as an executable on the `$PATH`. 171 | 172 | ## Nix flake 173 | 174 | The module is installable from its flake using Nix Home Manager. 175 | 176 | See my own [Home Manager flake](https://github.com/tesujimath/home.nix/blob/main/flake.nix#L12) and [nushell module](https://github.com/tesujimath/home.nix/blob/main/modules/nushell/default.nix) for hints how to achieve this. Note in particular the requirement for [each-time plugin registration](https://github.com/tesujimath/home.nix/blob/main/modules/nushell/config.nu#L761). 177 | 178 | ## Future work 179 | 180 | - unsetting an environment variable ought to be possible 181 | --------------------------------------------------------------------------------