Skip to main content
typo
Source Link

There are a fair bit of similar questions, but I can't find spec for this particular case.

I'm writing a shell script to verify bash configuration. For exmaple, I add test_alias to ~/.bashrc, which is also sourced from ~/.bash_profile so the configuration can be loaded both for interactive and login shell. And I am aiming to test this within shell script for the users who previously had ~/.bashrc but had not sourced that in profile before. So I want to programatically test against profile configuration at ~/.bash_profile, not ~/.bashrc.

Here's an exmaple setup.

~/.bashrc

alias alias_test='echo "Test succeeded."'

~/.bash_profile

source ~/.bashrc

Then I go to shell and test them.

# Try testing in one line command for login shell
# I excect this to load profile before running command 
# provided in option.
# However it doesn't seem to have loaded it.
% bash -lc "test-alias""test_alias"
> bash: line 1: alias_test: command not found

# Just to verify that the configuration itself is successful,
# if I try to do that interactively, it actually works.
% bash -l
[bash login shell] % test-aliastest_alias
[bash login shell] > Test succeeded.

# This works too, but this isn't what I want to test 
# as I understand that this directly loads `~/.bashrc` 
# even without configuring profile.
% bash -ic "test-alias""test_alias"
> Test succeeded.

This confuses me, because man bash does not seem to address this behavior.

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

This looks to me as though -l (or --login) changes shell initialization behavior depending on the other factors such as if -c is set or not. However for some reasons I can't find the documentation or source that sites this.

What am I missing here?


By the way, the environment I'm testing on is macOS and bash is the one installed by homebrew. (GNU bash, version 5.2.37(1)-release (aarch64-apple-darwin24.2.0)

There are a fair bit of similar questions, but I can't find spec for this particular case.

I'm writing a shell script to verify bash configuration. For exmaple, I add test_alias to ~/.bashrc, which is also sourced from ~/.bash_profile so the configuration can be loaded both for interactive and login shell. And I am aiming to test this within shell script for the users who previously had ~/.bashrc but had not sourced that in profile before. So I want to programatically test against profile configuration at ~/.bash_profile, not ~/.bashrc.

Here's an exmaple setup.

~/.bashrc

alias alias_test='echo "Test succeeded."'

~/.bash_profile

source ~/.bashrc

Then I go to shell and test them.

# Try testing in one line command for login shell
# I excect this to load profile before running command 
# provided in option.
# However it doesn't seem to have loaded it.
% bash -lc "test-alias"
> bash: line 1: alias_test: command not found

# Just to verify that the configuration itself is successful,
# if I try to do that interactively, it actually works.
% bash -l
[bash login shell] % test-alias
[bash login shell] > Test succeeded.

# This works too, but this isn't what I want to test 
# as I understand that this directly loads `~/.bashrc` 
# even without configuring profile.
% bash -ic "test-alias"
> Test succeeded.

This confuses me, because man bash does not seem to address this behavior.

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

This looks to me as though -l (or --login) changes shell initialization behavior depending on the other factors such as if -c is set or not. However for some reasons I can't find the documentation or source that sites this.

What am I missing here?


By the way, the environment I'm testing on is macOS and bash is the one installed by homebrew. (GNU bash, version 5.2.37(1)-release (aarch64-apple-darwin24.2.0)

There are a fair bit of similar questions, but I can't find spec for this particular case.

I'm writing a shell script to verify bash configuration. For exmaple, I add test_alias to ~/.bashrc, which is also sourced from ~/.bash_profile so the configuration can be loaded both for interactive and login shell. And I am aiming to test this within shell script for the users who previously had ~/.bashrc but had not sourced that in profile before. So I want to programatically test against profile configuration at ~/.bash_profile, not ~/.bashrc.

Here's an exmaple setup.

~/.bashrc

alias alias_test='echo "Test succeeded."'

~/.bash_profile

source ~/.bashrc

Then I go to shell and test them.

# Try testing in one line command for login shell
# I excect this to load profile before running command 
# provided in option.
# However it doesn't seem to have loaded it.
% bash -lc "test_alias"
> bash: line 1: alias_test: command not found

# Just to verify that the configuration itself is successful,
# if I try to do that interactively, it actually works.
% bash -l
[bash login shell] % test_alias
[bash login shell] > Test succeeded.

# This works too, but this isn't what I want to test 
# as I understand that this directly loads `~/.bashrc` 
# even without configuring profile.
% bash -ic "test_alias"
> Test succeeded.

This confuses me, because man bash does not seem to address this behavior.

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

This looks to me as though -l (or --login) changes shell initialization behavior depending on the other factors such as if -c is set or not. However for some reasons I can't find the documentation or source that sites this.

What am I missing here?


By the way, the environment I'm testing on is macOS and bash is the one installed by homebrew. (GNU bash, version 5.2.37(1)-release (aarch64-apple-darwin24.2.0)

edited tags; edited tags
Link
muru
  • 78.1k
  • 16
  • 213
  • 319
formatting
Source Link

There are a fair bit of similar questions, but I can't find spec for this particular case.

I'm writing a shell script to verify bash configuration. For exmaple, I add test_alias to ~/.bashrc, which is also sourced from ~/.bash_profile so the configuration can be loaded both for interactive and login shell. And I am aiming to test this within shell script for the users who previously had ~/.bashrc but had not sourced that in profile before. So I want to programatically test against profile configuration at ~/.bash_profile, not ~/.bashrc.

Here's an exmaple setup.

~/.bashrc

alias alias_test='echo "Test succeeded."'

~/.bash_profile

source ~/.bashrc

Then I go to shell and test them.

# Try testing in one line command for login shell
# I excect this to load profile before running command 
# provided in option.
# However it doesn't seem to have loaded it.
% bash -lc "test-alias"
> bash: line 1: alias_test: command not found

# Just to verify that the configuration itself is successful,
# if I try to do that interactively, it actually works.
% bash -l
[bash login shell] % test-alias
[bash login shell] > Test succeeded.

# This works too, but this isn't what I want to test 
# as I understand that this directly loads `~/.bashrc` 
# even without configuring profile.
% bash -ic "test-alias"
> Test succeeded.

This confuses me, because man bash does not seem to address this behavior.

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

This looks to me as though -l (or --login) changes shell initialization behavior depending on the other factors such as if -c is set or not. However for some reasons I can't find the documentation or source that sites this.

What am I missing here?


By the way, the environment I'm testing on is macOS and bash is the one installed by homebrew. (GNU bash, version 5.2.37(1)-release (aarch64-apple-darwin24.2.0)

There are a fair bit of similar questions, but I can't find spec for this particular case.

I'm writing a shell script to verify bash configuration. For exmaple, I add test_alias to ~/.bashrc, which is also sourced from ~/.bash_profile so the configuration can be loaded both for interactive and login shell. And I am aiming to test this within shell script for the users who previously had ~/.bashrc but had not sourced that in profile before. So I want to programatically test against profile configuration at ~/.bash_profile, not ~/.bashrc.

Here's an exmaple setup.

~/.bashrc

alias alias_test='echo "Test succeeded."'

~/.bash_profile

source ~/.bashrc

Then I go to shell and test them.

# Try testing in one line command for login shell
# I excect this to load profile before running command provided in option.
# However it doesn't seem to have loaded it.
% bash -lc "test-alias"
> bash: line 1: alias_test: command not found

# Just to verify that the configuration itself is successful,
# if I try to do that interactively, it actually works.
% bash -l
[bash login shell] % test-alias
[bash login shell] > Test succeeded.

# This works too, but this isn't what I want to test as I understand that this directly loads `~/.bashrc` even without configuring profile.
% bash -ic "test-alias"
> Test succeeded.

This confuses me, because man bash does not seem to address this behavior.

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

This looks to me as though -l (or --login) changes shell initialization behavior depending on the other factors such as if -c is set or not. However for some reasons I can't find the documentation or source that sites this.

What am I missing here?


By the way, the environment I'm testing on is macOS and bash is the one installed by homebrew. (GNU bash, version 5.2.37(1)-release (aarch64-apple-darwin24.2.0)

There are a fair bit of similar questions, but I can't find spec for this particular case.

I'm writing a shell script to verify bash configuration. For exmaple, I add test_alias to ~/.bashrc, which is also sourced from ~/.bash_profile so the configuration can be loaded both for interactive and login shell. And I am aiming to test this within shell script for the users who previously had ~/.bashrc but had not sourced that in profile before. So I want to programatically test against profile configuration at ~/.bash_profile, not ~/.bashrc.

Here's an exmaple setup.

~/.bashrc

alias alias_test='echo "Test succeeded."'

~/.bash_profile

source ~/.bashrc

Then I go to shell and test them.

# Try testing in one line command for login shell
# I excect this to load profile before running command 
# provided in option.
# However it doesn't seem to have loaded it.
% bash -lc "test-alias"
> bash: line 1: alias_test: command not found

# Just to verify that the configuration itself is successful,
# if I try to do that interactively, it actually works.
% bash -l
[bash login shell] % test-alias
[bash login shell] > Test succeeded.

# This works too, but this isn't what I want to test 
# as I understand that this directly loads `~/.bashrc` 
# even without configuring profile.
% bash -ic "test-alias"
> Test succeeded.

This confuses me, because man bash does not seem to address this behavior.

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

This looks to me as though -l (or --login) changes shell initialization behavior depending on the other factors such as if -c is set or not. However for some reasons I can't find the documentation or source that sites this.

What am I missing here?


By the way, the environment I'm testing on is macOS and bash is the one installed by homebrew. (GNU bash, version 5.2.37(1)-release (aarch64-apple-darwin24.2.0)

formatting
Source Link
Loading
Clarify the intent.
Source Link
Loading
Source Link
Loading