You are not logged in.

#1 2025-06-16 02:31:20

hanss
Member
Registered: 2025-06-16
Posts: 18

Why does .bash_profile not check interactivity when sourcing .bashrc?

In /etc/profile there are a number of conditions on sourcing /etc/bash.bashrc:

# Source global bash config, when interactive but not posix or sh mode
if test "$BASH" &&\
   test "$PS1" &&\
   test -z "$POSIXLY_CORRECT" &&\
   test "${0#-}" != sh &&\
   test -r /etc/bash.bashrc
then
	. /etc/bash.bashrc
fi

Compared to ~/.bash_profile which checks only for existence before sourcing ~/.bashrc:

[[ -f ~/.bashrc ]] && . ~/.bashrc

I think I understand why the first, third, and fourth tests are not need: unlike /etc/profile, ~/.bash_profile will only ever be read by bash and not if bash is in POSIX or sh mode.

However I don't understand why the second test of PS1 for interactivity would not also be needed in ~/.bash_profile. If I understand correctly that test comes into play in the case of a non-interactive shell with the --login option. So then why is it ok for a non-interactive --login shell to source ~/.bashrc but not /etc/bash.bashrc? Or am I confused about when these conditions apply?

I have also come across suggestions that ~/.bash_profile should check for interactivity before sourcing ~/.bashrc, for example:
Unix & Linux Stack Exchange - Why might one add ~/.profile to ~/.bash_profile?

... Hence, for most people, ~/.bash_profile should consist of these two lines:

. ~/.profile
case  $- in *i*) . ~/.bashrc;; esac

Offline

#2 2025-06-16 02:50:32

hanss
Member
Registered: 2025-06-16
Posts: 18

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

Ok, I see a check for interactivity is included at the top of both /etc/bash.bashrc and /etc/skel/.bashrc:

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

So is the test of PS1 in /etc/profile redundant or does is have some other pupose as well?

Offline

#3 2025-06-16 08:04:28

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 369

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

hanss wrote:

Ok, I see a check for interactivity is included at the top of both /etc/bash.bashrc and /etc/skel/.bashrc:

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

I think there is a big mess in profile/rc files.

~/.bashrc is not (should not) be read by non-interactive shell.
/etc/profile (and /etc/bash.bashrc) is not (should not) be read by non-login shell.

Seems all that checks purposed to workaround user's misunderstanding what commands should be placed to what file.

Offline

#4 2025-06-18 22:32:02

ayekat
Member
Registered: 2011-01-17
Posts: 1,622

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

dimich wrote:

/etc/profile (and /etc/bash.bashrc) is not (should not) be read by non-login shell.

/etc/bash.bashrc is read by a non-login bash if it's interactive, though. This is defined by the -DSYS_BASHRC compilation flag in the bash PKGBUILD.

That being said, I find it ugly that Arch needs to ship an /etc/profile with bash-specific code in it because of bash's awkward startup behaviour¹ (see INVOCATION in bash(1)).

_____
¹ I was about to patch the bash stuff out from /etc/profile when I realised that: 'Wait, no, bash by itself can't do things correctly—an interactive login bash wouldn't read the bashrc file defined by -DSYS_BASHRC despite being an interactive shell'.


pkgshackscfgblag

Offline

#5 2025-06-18 23:52:33

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 369

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

ayekat wrote:

/etc/bash.bashrc is read by a non-login bash if it's interactive, though. This is defined by the -DSYS_BASHRC compilation flag in the bash PKGBUILD.

Ugh. And no word about this in manual page hmm

ayekat wrote:

That being said, I find it ugly that Arch needs to ship an /etc/profile with bash-specific code

As well as doublesourcing guard in /etc/bash.bashrc.

Offline

#6 2025-06-20 06:05:13

hanss
Member
Registered: 2025-06-16
Posts: 18

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

Every few years I go to clean and organize up my configuration files and make some attempt to remember/understand these details, which I usually end up regretting. I also noticed /etc/profile is in the filesystem package while the others are the the bash package. Perhaps that explains the apparently redundant tests in /etc/profile and /etc/bash.bashrc.

ayekat wrote:

... I find it ugly that Arch needs to ship an /etc/profile with bash-specific code in it because of bash's awkward startup behaviour¹ (see INVOCATION in bash(1)).

_____
¹ I was about to patch the bash stuff out from /etc/profile when I realised that: 'Wait, no, bash by itself can't do things correctly—an interactive login bash wouldn't read the bashrc file defined by -DSYS_BASHRC despite being an interactive shell'.

Yes, I believe this matches my understanding... bash itself will not source the bashrc files if it's not running interactively and the choice to source them from the profile code in the interactive login case is made by the distribution? If so I think it would be less confusing to keep the interactivity tests in the profile code where the choice to deviate from default bash behavior is made, rather than in the bashrc code where the presence of those checks is confusing without knowing why there would even be an attempt to source them in the non-interactive case.

By bash-specific you mean related to bash but not necessarily using bash-specific syntax/features, right? And the bit I posted from /etc/profile, despite doing checks related to bash, is all POSIX sh?

Last edited by hanss (2025-06-20 06:08:13)

Offline

#7 2025-06-21 23:29:22

ayekat
Member
Registered: 2011-01-17
Posts: 1,622

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

hanss wrote:

[…] the choice to source them from the profile code in the interactive login case is made by the distribution?

Or by the user (in case of the files in the home directory). But yes, one has to source the bashrc file(s) from the login/profile file(s) in bash, otherwise some interactive shells (the interactive login shell) would end up not sourcing bashrc, which is probaly almost never what the user wants.
Why bash decided to source files the way it does is beyond me.

By bash-specific you mean related to bash but not necessarily using bash-specific syntax/features, right? And the bit I posted from /etc/profile, despite doing checks related to bash, is all POSIX sh?

Yes, the code in /etc/profile is POSIX compliant, but it does still do some bash-specific things.


pkgshackscfgblag

Offline

#8 2025-06-22 06:51:08

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

There's benefit to not sourcing bashrc in interactive login shells since
1. bashrc is likely where users fuck up
2. interactive login bash == console login what for 99+% of users means "something's gone wrong"

Whether that's actually  the motivation, idk.

Offline

#9 2025-06-22 12:33:09

ayekat
Member
Registered: 2011-01-17
Posts: 1,622

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

3. SSH sessions


pkgshackscfgblag

Offline

#10 2025-06-22 12:47:14

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

True, but if you frequently use a system via ssh (headless server) you can source bashrc - maybe even w/ a timer'd read so you can bail out of that w/ a keypress (because screwing up a remote shell to the point where it becomes dysfunctional will probably suck)

Offline

#11 2025-06-22 18:07:44

hanss
Member
Registered: 2025-06-16
Posts: 18

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

Not sure I'm following the last 4 posts... so bash has special handling to detect RSH/SSH and treats that as interactive login, right? Are we saying it's desirable or undesirable to have bashrc sourced in that case?

I also noticed the bash manual mentions sourcing bashrc from profile but nothing about making it conditional on interactivity:

Invoked as an interactive non-login shell:

When an interactive shell that is not a login shell is started, Bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force Bash to read and execute commands from file instead of ~/.bashrc.

So, typically, your ~/.bash_profile contains the line

if [ -f ~/.bashrc ]; then . ~/.bashrc; fi

after (or before) any login-specific initializations.

So apparently bash developers think it is not a problem to source bashrc in the non-interactive login case, but the Arch package needs to add the interactivity tests for some Arch-specific reason?

Offline

#12 2025-06-22 19:37:41

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

so bash has special handling to detect RSH/SSH and treats that as interactive login, right?

No. A ssh login is an interactive login shell.
I suggested that one *could* discriminate that case (basically check whether this is a tty or pts) to decide whether to source bashrc if one frequently operates the system via ssh

So apparently bash developers think it is not a problem to source bashrc in the non-interactive login case

Apparently.

but the Arch package needs to add the interactivity tests for some Arch-specific reason?

No, no and no.
The last posts are just a tangential discussion as to why bash does not automatically source bashrc on interactive login shells (but requires you to do so manually from your profile - if you so desire)

Offline

#13 2025-06-22 22:55:13

hanss
Member
Registered: 2025-06-16
Posts: 18

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

seth wrote:
hanss wrote:

so bash has special handling to detect RSH/SSH and treats that as interactive login, right?

No. A ssh login is an interactive login shell.
I suggested that one *could* discriminate that case (basically check whether this is a tty or pts) to decide whether to source bashrc if one frequently operates the system via ssh

That was something I remembered reading, went back and looked, it's in the section of the bash manual about startup files:

Invoked by remote shell daemon
Bash attempts to determine when it is being run with its standard input connected to a network connection, as when executed by the historical remote shell daemon, usually rshd, or the secure shell daemon sshd. If Bash determines it is being run non-interactively in this fashion, it reads and executes commands from ~/.bashrc, if that file exists and is readable. It will not do this if invoked as sh. The --norc option may be used to inhibit this behavior, and the --rcfile option may be used to force another file to be read, but neither rshd nor sshd generally invoke the shell with those options or allow them to be specified.

I interpret that to be implying that the way the daemons invoke bash would normally be considered non-interactive but bash detects the daemons as a special case and goes ahead and runs in interactive mode instead?

seth wrote:
hanss wrote:

but the Arch package needs to add the interactivity tests for some Arch-specific reason?

No, no and no.
The last posts are just a tangential discussion as to why bash does not automatically source bashrc on interactive login shells (but requires you to do so manually from your profile - if you so desire)

Ignoring profile since I don't think there's any confusion about it, as far as I understand so far the cases where bashrc are sourced are:

  • bash alone: I/NL

  • bash plus recommended unconditional sourcing of bashrc from profile: I/NL, I/L, NI/L

  • Arch (source bashrc from profile only if interactive): I/NL, I/L

So Arch differs from either of those "default" bash behaviors, or did I get mixed up somewhere?

Offline

#14 2025-06-23 06:33:58

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

https://wiki.archlinux.org/title/Bash#C … tion_files
"arch" has

bash plus recommended unconditional sourcing of bashrc from profile

in /etc/skel/.bash_profile so for all intents and purposes "defaults" to that.

normally be considered non-interactive but bash detects the daemons as a special case and goes ahead and runs in interactive mode instead?

Sounds like, but that's an implementation detail - is you ssh into a system, you're using that shell interactively, so it's reasonable to expect it to behave as such.

Offline

#15 2025-06-23 07:20:28

hanss
Member
Registered: 2025-06-16
Posts: 18

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

seth wrote:

https://wiki.archlinux.org/title/Bash#C … tion_files
"arch" has

hanss wrote:

bash plus recommended unconditional sourcing of bashrc from profile

in /etc/skel/.bash_profile so for all intents and purposes "defaults" to that.

That is what got me confused in the first place, but as far as I can tell it doesn't. Going back to the snippets in the first two posts, the sourcing of .bashrc from .bash_profile is unconditional as you point out but /etc/skel/.bashrc has that guard at the top which returns immediately in the non-interactive case. And /etc/profile checks PS1 before sourcing /etc/bash.bashrc which also has the same guard at the top. That part seems redundant unless there is another way for /etc/bash.bashrc to get sourced?

Last edited by hanss (2025-06-23 07:20:46)

Offline

#16 2025-06-23 07:59:21

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

but /etc/skel/.bashrc has that guard at the top which returns immediately in the non-interactive case

Which is ok, you don't want a non-interactive shell to bloat-source .bashrc
The non-interactive shell is the script parser when running anything #!/bin/bash

etc/profile seeks to condition /etc/bash.bashrc on hints of an interactive bash, the $PS1 test in bash.bashrc only conditions setting a specific PS1

Offline

#17 2025-06-23 13:46:18

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 369

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

seth wrote:

but /etc/skel/.bashrc has that guard at the top which returns immediately in the non-interactive case

Which is ok, you don't want a non-interactive shell to bloat-source .bashrc

But why non-interactive bash ever sources .bashrc?

Offline

#18 2025-06-23 13:54:46

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

Because someone sources it from bash_profile wink
I think this is really just a rail-guard against explicit sources eg. from non-interactive login shells.

Offline

#19 2025-06-23 14:40:29

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 369

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

seth wrote:

Because someone sources it from bash_profile wink

Why not check for interactivity in ~/.bash_profile then? (rhetorical question).

[[ $- == *i* ]] && [[ -f ~/.bashrc ]] && . ~/.bashrc

Offline

#20 2025-06-23 16:49:40

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

Rhetorical answer: proximal defense.
You want to prevent this from loading in interactive shells, no matter what tries to source it.
So you can either add a fence right in front of it that will always apply - or you can add little fences to every single possible file that might end up sourcing it through the most convoluted detour thinkable.
Both are possible, but one is tedious and the other is robust and simple.

Offline

#21 2025-06-23 18:37:29

hanss
Member
Registered: 2025-06-16
Posts: 18

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

Regardless of where the checks happen, the end result is that bash with the recommended unconditional sourcing will source .bashrc in the non-interactive login case while Arch with it's extra conditions will not, right? In other words, these two lines in the list I made earlier:

hanss wrote:
  • bash plus recommended unconditional sourcing of bashrc from profile: I/NL, I/L, NI/L

  • Arch (source bashrc from profile only if interactive): I/NL, I/L

Regarding the non-interactive login case:

seth wrote:

The non-interactive shell is the script parser when running anything #!/bin/bash

But script parsing is typically non-interactive non-login, right? Not non-interactive login which is the case where bash and Arch differ.

I don't know how often the non-interactive login case is used, or for what purpose, just trying to understand where the decisions come from.

To make sure I follow:

seth wrote:
hanss wrote:

So apparently bash developers think it is not a problem to source bashrc in the non-interactive login case

Apparently.

seth wrote:
hanss wrote:

but /etc/skel/.bashrc has that guard at the top which returns immediately in the non-interactive case

Which is ok, you don't want a non-interactive shell to bloat-source .bashrc
The non-interactive shell is the script parser when running anything #!/bin/bash

So basically, sourcing .bashrc in the non-interactive login case is pointless but also harmless? And whoever wrote the bash manual doesn't bother adding extra conditions to avoid it, while the Arch packagers do add those extra conditions to avoid bloat?

Offline

#22 2025-06-23 21:09:30

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

bash with the recommended unconditional sourcing will source .bashrc in the non-interactive login case while Arch with it's extra conditions will not, right?

Wrong, the bashrc gets unconditionally sourced by the skel provided .bash_profile - it's just that the bashrc immediately aborts in the non-interactive case.

Why do you think "arch" does anything non-standard here?
There's
1. the default builtin bash behavior
2. custom bash_profile and bashrc's where you maybe get some distro default but are ultimately every users own preference

The debian default bashrc does the exact same immediate abort in non-interactive bashrc, http://deb.debian.org/debian/pool/main/ … ian.tar.xz because that's the only reasonable thing to do.

I don't quite understand where you're trying to go with this?

So basically, sourcing .bashrc in the non-interactive login case is pointless but also harmless?

Depends on what you do in your bashrc, if you alias some commmand the session startup script relies on acting a certain way, you can screw it up royally.

The whole point of the bashrc is to add fancy and convenient customizations meant to make your interactive session a more pleasant experience.
In any other context this ends up being at best bloat and and worst interference, so it is a very good idea to skip that stuff in non-interactive shells.

Offline

#23 Yesterday 02:54:28

hanss
Member
Registered: 2025-06-16
Posts: 18

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

seth wrote:
hanss wrote:

]bash with the recommended unconditional sourcing will source .bashrc in the non-interactive login case while Arch with it's extra conditions will not, right?

Wrong, the bashrc gets unconditionally sourced by the skel provided .bash_profile - it's just that the bashrc immediately aborts in the non-interactive case.

I understand the behavior of those snippets I posted initially that the first non-comment, non-whitespace line of .bashrc gets sourced in that case. However the remaining "body" where user-added stuff would typically be put does not. bash.bashrc does not get sourced at all due to the PS1 test in profile. So to clarify, I've been talking about conditions for the "bodies" of the bashrc files (/etc/skel/.bashrc and /etc/bash.bashrc) to be sourced regardless of whether the check happens in the sourcing code or at the top of the sourced code.

seth wrote:

Why do you think "arch" does anything non-standard here?

I didn't mean to imply any sort of judgement favoring one or the other. There was not much documentation I could find about the non-interactive login case specifically which is where the difference is, just some blurbs like:

Difference between Login Shell and Non-Login Shell?:

It's rare to run a non-interactive login shell, but some X settings do that when you log in with a display manager, so as to arrange to read the profile files. Other settings (this depends on the distribution and on the display manager) read /etc/profile and ~/.profile explicitly, or don't read them. Another way to get a non-interactive login shell is to log in remotely with a command passed through standard input which is not a terminal, e.g. ssh example.com <my-script-which-is-stored-locally (as opposed to ssh example.com my-script-which-is-on-the-remote-machine, which runs a non-interactive, non-login shell).

Linux Professional Institute - 105.1 Lesson 1:

Non-interactive login shells are quite rare and impractical. Their uses are virtually non-existent and we will only comment on them for the sake of insight into shell behaviour. Some odd examples include forcing a script to be run from a login shell with /bin/bash --login <some_script> or piping the standard output (stdout) of a command into the standard input (stdin) of an ssh connection: <some_command> | ssh <some_user>@<some_server>

I saw some mentions that cron and similar use non-interactive login shells but it sounds like systemd tightly controls the environment itself so the behavior could differ from any of the 4 bash plus startup file cases.

seth wrote:

I don't quite understand where you're trying to go with this?

I could imagine getting an answer like, "Arch uses non-interactive login shell in xyz specific situation where it's important not to source .bashrc." Or equally well, "Non-interactive login shell is a weird case no one uses on purpose so it doesn't really matter and Arch just put those checks there because that's what Debian did." Or anything in between really, I don't know. Again, I'm specifically wondering about the non-interactive login case. Various reason given above for not sourcing .bashrc make sense to me for the non-interactive non-login case, but I'm still wondering when/why the non-interactive login case would be used...? And if it's just considered an odd/invalid combination that is not used on purpose then why does Arch add extra logic related to it?

Offline

#24 Yesterday 17:34:30

seth
Member
Registered: 2012-09-03
Posts: 64,806

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

There was not much documentation I could find about the non-interactive login case specifically which is where the difference is

Difference to what?

"Arch" doesn't use non-interactive login shells, they might or not be relevant to various DMs when launching the user session - there's no standard here and the DMs all act somewhat different.

reason given above for not sourcing .bashrc make sense to me for the non-interactive non-login case

The dominant condition is "non-interactive", "login shell" is really an irrelevant detail here - there's no point in executing what you're supposed to put in bashrc in a non-interactive case.
One might argue that the default, built-in behavior hinges on the idea that login shells are never interactive and you'd eg. substitute your login shell w/ "exec bash" and users later on figured "nah, I'll just automatically source my bashrc after the login" - until GUIs became popular where now the reality (ssh aside) is that your login shell isn't interactive and all bash instances you ever see are non-login shells in some GUI terminal emulator.

The most likely explanation for the status quo is indeed

Arch just put those checks there because that's what Debian did pretty much everyone else does

Why any of this has been historically this way is however less important than knowing /that/ it is, what is sourced when and how you can control and structure your shell function additions.
Eg. I've an entire set of convenience function that I only load in one specific shell that then can act as a quick calculator process launcher w/ various aliases and convenience functions that I don't even want in a regular terminal (because of the completely twisted default behavior of commands) and most certainly not in a script interpreter, because it'd likely break half of all bash scripts.

Offline

#25 Yesterday 18:45:00

hanss
Member
Registered: 2025-06-16
Posts: 18

Re: Why does .bash_profile not check interactivity when sourcing .bashrc?

seth wrote:
hanss wrote:

There was not much documentation I could find about the non-interactive login case specifically which is where the difference is

Difference to what?

The behavior of bash alone plus the recommendation in the manual to unconditionally source bashrc from profile with no mention of including guards against interactive sourcing at the top the bashrc files. Unconditional sourcing of bashrc from profile does not result in bashrc being sourced in the common non-interactive non-login case because in that case profile is not sourced either. So the non-interactive login case is the only one where the guards against interactive sourcing included at the top of Arch's bashrc files actually change what gets sourced compared to unconditional sourcing from profile, assuming I understand all that correctly...

seth wrote:
hanss wrote:

reason given above for not sourcing .bashrc make sense to me for the non-interactive non-login case

The dominant condition is "non-interactive", "login shell" is really an irrelevant detail here...

If what you're getting at here is that the conditions should be independent, so that the behavior can be summarized simply as "profile sourced if the shell is login, bashrc sourced if the shell is interactive" then I agree that seems logical and it is the end result in Arch. However that's not what bash alone does, and it's not exactly what bash with the recommended unconditional sourcing of bashrc from profile does either. I have not come across anyone claiming "bash's handling of startup files is perfectly logical and makes so much sense to me", generally quite the opposite, but I was still interested in trying to track down if there is some logic behind the way bash does it and the recommendation in the manual.

seth wrote:

Eg. I've an entire set of convenience function that I only load in one specific shell that then can act as a quick calculator process launcher w/ various aliases and convenience functions that I don't even want in a regular terminal (because of the completely twisted default behavior of commands) and most certainly not in a script interpreter, because it'd likely break half of all bash scripts.

But the behavior of bash alone, or bash with unconditional sourcing of bashrc form profile, will not result in your .bashrc breaking your non-interactive non-login scripts either, even without the additional conditions/guards Arch has to prevent non-interactive sourcing the bodies of the bashrc files. Because in the normal non-interactive non-login case profile is not sourced anyways.

Again, I agree it would seem logical for interactive and login to be independent conditions such that interactive alone determines whether the bashrc files are sourced and login alone determines whether the profile files are sourced, but bash doesn't seem to see it that way...

Offline

Board footer

Powered by FluxBB

OSZAR »