https://lists.gnu.org/archive/html/bug-bash/2026-05/msg00037.html (https://lists.gnu.org/archive/html/bug-bash/2026-05/msg00063.html) https://lists.gnu.org/archive/html/bug-bash/2026-05/msg00054.html From b1d9695f781bd53f1d30781b26f1fbbcbb6d2eb6 Mon Sep 17 00:00:00 2001 Message-ID: From: Kerin Millar Date: Sun, 31 May 2026 19:55:28 +0200 Subject: [PATCH] execute_cmd.c: avoid export-environment rebuilds in comsubs This is a partial backport of commit 2d4ba0c61858 from the devel branch. It addresses a performance regression affecting command substitutions with large exported environments. execute_cmd.c - execute_disk_command: if we update SHLVL, do it after (maybe) making the export environment and then update the export env in place, so we don't have to rebuild it twice or rebuild it more times than necessary Link: https://git.savannah.gnu.org/cgit/bash.git/commit/?id=2d4ba0c61858 Signed-off-by: Kerin Millar --- execute_cmd.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/execute_cmd.c b/execute_cmd.c index 6a22395e..739991f9 100644 --- execute_cmd.c +++ execute_cmd.c @@ -5814,9 +5814,17 @@ execute_disk_command (WORD_LIST *words, REDIRECT *redirects, char *command_line, shell level like `exec' would do. Don't do this if we are already in a pipeline environment, assuming it's already been done. */ if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE && (subshell_environment & SUBSHELL_PIPE) == 0) - adjust_shell_level (-1); - - maybe_make_export_env (); + { + maybe_make_export_env (); + adjust_shell_level (-1); + update_export_env_inplace ("SHLVL=", 6, get_string_value ("SHLVL")); + /* adjust_shell_level() marks the export environment dirty because SHLVL is + exported. Since we have already built the environment, update SHLVL in place + below and avoid forcing a full rebuild here. */ + array_needs_making = 0; + } + else + maybe_make_export_env (); put_command_name_into_env (command); } else if (command == 0 && notfound_str == 0) /* make sure */ -- 2.56.0