Skip to content

Commit

Permalink
make exec command decrement SHLVL correctly & SHLVL related test (#14707
Browse files Browse the repository at this point in the history
)

# Description

Rework of #14570, fixing #14567.

`exec` will decrement `SHLVL` env value before passing it to target
executable (in interactive mode).

(Same as last pr, but this time there's no wrong change to current
working code)

Two `SHLVL` related tests were also added this time.
  • Loading branch information
rikukiix authored Dec 31, 2024
1 parent e7877db commit 4884894
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
10 changes: 10 additions & 0 deletions crates/nu-command/src/system/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ On Windows based systems, Nushell will wait for the command to finish and then e
let envs = env_to_strings(engine_state, stack)?;
command.env_clear();
command.envs(envs);
// Decrement SHLVL as removing the current shell from the stack
// (only works in interactive mode, same as initialization)
if engine_state.is_interactive {
let shlvl = engine_state
.get_env_var("SHLVL")
.and_then(|shlvl_env| shlvl_env.coerce_str().ok()?.parse::<i64>().ok())
.unwrap_or(1)
.saturating_sub(1);
command.env("SHLVL", shlvl.to_string());
}

// Configure args.
let args = crate::eval_arguments_from_call(engine_state, stack, call)?;
Expand Down
20 changes: 20 additions & 0 deletions tests/shell/environment/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,23 @@ fn std_log_env_vars_have_defaults() {
assert!(actual.err.contains("%MSG%"));
assert!(actual.err.contains("%Y-"));
}

#[test]
fn env_shlvl() {
let actual = nu!("
$env.SHLVL = 5
nu -i -c 'print $env.SHLVL'
");

assert_eq!(actual.out, "6");
}

#[test]
fn env_shlvl_in_exec() {
let actual = nu!("
$env.SHLVL = 29
nu -i -c \"exec nu -i -c 'print $env.SHLVL'\"
");

assert_eq!(actual.out, "30");
}

0 comments on commit 4884894

Please sign in to comment.