Skip to content

Commit

Permalink
feat: implement SHLVL
Browse files Browse the repository at this point in the history
  • Loading branch information
39555 committed Oct 27, 2024
1 parent a7d77ff commit 397bdf3
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
32 changes: 31 additions & 1 deletion brush-core/src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,17 @@ pub struct Shell {

impl Clone for Shell {
fn clone(&self) -> Self {
let mut env = self.env.clone();

if !self.options.sh_mode {
increment_level_var(&mut env, "BASH_SUBSHELL", 1, false).unwrap();
}

Self {
traps: self.traps.clone(),
open_files: self.open_files.clone(),
working_dir: self.working_dir.clone(),
env: self.env.clone(),
env,
funcs: self.funcs.clone(),
options: self.options.clone(),
jobs: jobs::JobManager::new(),
Expand Down Expand Up @@ -279,7 +285,13 @@ impl Shell {
)?;
}

increment_level_var(&mut env, "SHLVL", 1, true)?;

if !options.sh_mode {
let mut lvl = ShellVariable::new("0".into());
lvl.export();
env.set_global("BASH_SUBSHELL", lvl)?;

if let Some(shell_name) = &options.shell_name {
env.set_global("BASH", ShellVariable::new(shell_name.into()))?;
}
Expand Down Expand Up @@ -1182,3 +1194,21 @@ fn parse_string_impl(
tracing::debug!(target: trace_categories::PARSE, "Parsing string as program...");
parser.parse(true)
}

// parse numeric variable from string and increment it + 1, then reexport
fn increment_level_var(
env: &mut ShellEnvironment,
var: &str,
default: usize,
export: bool,
) -> Result<(), error::Error> {
let lvl = env
.get_str(var)
.and_then(|s| s.parse::<usize>().ok().map(|n| n + 1))
.unwrap_or(default);
let mut lvl = ShellVariable::new(ShellValue::String(lvl.to_string()));
if export {
lvl.export();
}
env.set_global(var, lvl)
}
34 changes: 34 additions & 0 deletions brush-shell/tests/cases/compound_cmds/subshell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,37 @@ cases:
- name: "Piped subshell usage"
stdin: |
(echo hi) | wc -l
- name: "SHLVL subshell"
stdin: |
initial="$SHLVL"
function rec_subshell {
if [ "$1" -ge "$2" ]; then
exit
else
(
test $initial -eq $SHLVL; echo $?
rec_subshell $(($1 + 1)) $2
)
fi
}
rec_subshell 1 10
- name: "BASH_SUBSHELL"
stdin: |
initial="$BASH_SUBSHELL"
function rec_subshell {
if [ "$1" -ge "$2" ]; then
exit
else
(
test $initial -ne $BASH_SUBSHELL; echo $?
echo $BASH_SUBSHELL
initial=$BASH_SUBSHELL
rec_subshell $(($1 + 1)) $2
)
fi
}
rec_subshell 1 10

0 comments on commit 397bdf3

Please sign in to comment.