hello, Please consider these two patches for inclusion in bash to support storing shell initialisation files (profile, bashrc) in a subdirectory of ~/.config/ as most programs do these days.
I'm happy to make changes to address any feedback. Even if you'd prefer not to apply the second patch, applying the first patch is a nice cleanup and would make it easier for distributions such as Fedora to apply the second patch for themselves. Thank you very much for your consideration, Allison
From 282befe3579897174288075810a6c1d89df7a29f Mon Sep 17 00:00:00 2001 From: Allison Karlitskaya <allison.karlitsk...@redhat.com> Date: Fri, 7 May 2021 11:11:55 +0200 Subject: [PATCH 2/2] shell: add ~/.config/bash/ startup script options Introduce an alternate location for storing a profile and bashrc file, inside ~/.config/bash. This is mostly compatible with the XDG Base Directory Specification[1], but doesn't support expanding the XDG_CONFIG_HOME environment variable, which would require a larger patch with string manipulation/pasting. [1] https://specifications.freedesktop.org/basedir-spec/ --- doc/bash.1 | 21 ++++++++++++++------- shell.c | 5 +++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/doc/bash.1 b/doc/bash.1 index 5af7d428..69aa9853 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -188,6 +188,8 @@ Display a usage message on standard output and exit successfully. Execute commands from .I file instead of the standard personal initialization file +.I ~/.config/bash/bashrc +or .I ~/.bashrc if the shell is interactive (see .SM @@ -219,6 +221,8 @@ below). .TP .B \-\-norc Do not read and execute the personal initialization file +.I ~/.config/bash/bashrc +or .I ~/.bashrc if the shell is interactive. This option is on by default if the shell is invoked as @@ -318,9 +322,10 @@ is invoked as an interactive login shell, or as a non-interactive shell with the \fB\-\-login\fP option, it first reads and executes commands from the file \fI/etc/profile\fP, if that file exists. -After reading that file, it looks for \fI~/.bash_profile\fP, -\fI~/.bash_login\fP, and \fI~/.profile\fP, in that order, and reads -and executes commands from the first one that exists and is readable. +After reading that file, it looks for \fI~/.config/bash/profile\fP, +\fI~/.bash_profile\fP, \fI~/.bash_login\fP, and \fI~/.profile\fP, in that +order, and reads and executes commands from the first one that exists and +is readable. The .B \-\-noprofile option may be used when the shell is started to inhibit this behavior. @@ -333,8 +338,9 @@ exists. .PP When an interactive shell that is not a login shell is started, .B bash -reads and executes commands from \fI~/.bashrc\fP, if that file exists. -This may be inhibited by using the +looks for \fI~/.config/bash/bashrc\fP, and \fI~/.bashrc\fP, in that +order, and reads and executes commands from the first one that exists and +is readable. This may be inhibited by using the .B \-\-norc option. The \fB\-\-rcfile\fP \fIfile\fP option will force @@ -424,8 +430,9 @@ connected to a network connection, as when executed by the remote shell daemon, usually \fIrshd\fP, or the secure shell daemon \fIsshd\fP. If .B bash -determines it is being run in this fashion, it reads and executes -commands from \fI~/.bashrc\fP, if that file exists and is readable. +determines it is being run in this fashion, it reads and executes commands +from the first one of \fI~/.config/bash/bashrc\fP, and \fI~/.bashrc\fP, +which exists and is readable. It will not do this if invoked as \fBsh\fP. The .B \-\-norc diff --git a/shell.c b/shell.c index 6327e72d..c14c1844 100644 --- a/shell.c +++ b/shell.c @@ -1104,7 +1104,8 @@ execute_profile () if (!act_like_sh) { - if (maybe_execute_file ("~/.bash_profile", 1) || + if (maybe_execute_file ("~/.config/bash/profile", 1) || + maybe_execute_file ("~/.bash_profile", 1) || maybe_execute_file ("~/.bash_login", 1)) return; } @@ -1125,7 +1126,7 @@ execute_bashrc () if (bashrc_file) maybe_execute_file (bashrc_file, 1); - else + else if (maybe_execute_file ("~/.config/bash/bashrc", 1) == 0) maybe_execute_file (DEFAULT_BASHRC, 1); } -- 2.31.1
From 5d6a04c8594f9441b12c1a7485a4106b03bd2b03 Mon Sep 17 00:00:00 2001 From: Allison Karlitskaya <allison.karlitsk...@redhat.com> Date: Fri, 7 May 2021 10:59:09 +0200 Subject: [PATCH 1/2] shell: reduce duplication with startup files The logic for deciding which startup files to run currently includes two separate copies of the bashrc (system vs homedir), and the profile (system vs homedir, posix vs bash). Create two separate functions to handle the "profile" vs "bashrc" cases without duplicating the file lists. Meanwhile, the handling of the `--rcfile` option works by preseeding the option value to the default of "~/.bashrc" and overriding it when the user specifies the option. That works nicely, but only because we only consider exactly one possible bashrc file (which will stop being true with the following commit). Rework this a little to make the `--rcfile` option act as an override, which is set to NULL in case the flag isn't specified. In that case, we will fall back to the default bashrc. This commit is a pure refactor. It introduces no functional changes. --- shell.c | 85 +++++++++++++++++++++++++++------------------------------ 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/shell.c b/shell.c index ce8087f7..6327e72d 100644 --- a/shell.c +++ b/shell.c @@ -192,7 +192,7 @@ int have_devfd = 0; #endif /* The name of the .(shell)rc file. */ -static char *bashrc_file = DEFAULT_BASHRC; +static char *bashrc_file; /* Non-zero means to act more like the Bourne shell on startup. */ static int act_like_sh; @@ -1095,6 +1095,40 @@ execute_env_file (env_file) } } +/* Execute /etc/profile and one of the personal login shell + initialization files. */ +static void +execute_profile () +{ + maybe_execute_file (SYS_PROFILE, 1); + + if (!act_like_sh) + { + if (maybe_execute_file ("~/.bash_profile", 1) || + maybe_execute_file ("~/.bash_login", 1)) + return; + } + + maybe_execute_file ("~/.profile", 1); +} + +static void +execute_bashrc () +{ +#ifdef SYS_BASHRC +# if defined (__OPENNT) + maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1); +# else + maybe_execute_file (SYS_BASHRC, 1); +# endif +#endif + + if (bashrc_file) + maybe_execute_file (bashrc_file, 1); + else + maybe_execute_file (DEFAULT_BASHRC, 1); +} + static void run_startup_files () { @@ -1117,17 +1151,7 @@ run_startup_files () /* If we were run by sshd or we think we were run by rshd, execute ~/.bashrc if we are a top-level shell. */ if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2) - { -#ifdef SYS_BASHRC -# if defined (__OPENNT) - maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1); -# else - maybe_execute_file (SYS_BASHRC, 1); -# endif -#endif - maybe_execute_file (bashrc_file, 1); - return; - } + execute_bashrc (); } #if defined (JOB_CONTROL) @@ -1150,18 +1174,8 @@ run_startup_files () /* We don't execute .bashrc for login shells. */ no_rc++; - /* Execute /etc/profile and one of the personal login shell - initialization files. */ if (no_profile == 0) - { - maybe_execute_file (SYS_PROFILE, 1); - - if (act_like_sh) /* sh */ - maybe_execute_file ("~/.profile", 1); - else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) && - (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */ - maybe_execute_file ("~/.profile", 1); - } + execute_profile (); sourced_login = 1; } @@ -1186,32 +1200,13 @@ run_startup_files () /* We don't execute .bashrc for login shells. */ no_rc++; - /* Execute /etc/profile and one of the personal login shell - initialization files. */ if (no_profile == 0) - { - maybe_execute_file (SYS_PROFILE, 1); - - if (act_like_sh) /* sh */ - maybe_execute_file ("~/.profile", 1); - else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) && - (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */ - maybe_execute_file ("~/.profile", 1); - } + execute_profile (); } /* bash */ if (act_like_sh == 0 && no_rc == 0) - { -#ifdef SYS_BASHRC -# if defined (__OPENNT) - maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1); -# else - maybe_execute_file (SYS_BASHRC, 1); -# endif -#endif - maybe_execute_file (bashrc_file, 1); - } + execute_bashrc (); /* sh */ else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0) execute_env_file (get_string_value ("ENV")); @@ -2007,7 +2002,7 @@ shell_reinitialize () /* Ensure that the default startup file is used. (Except that we don't execute this file for reinitialized shells). */ - bashrc_file = DEFAULT_BASHRC; + bashrc_file = NULL; /* Delete all variables and functions. They will be reinitialized when the environment is parsed. */ -- 2.31.1