为什么切换用户时不读取.bashrc?

为什么切换用户时不读取.bashrc?

在 RHEL7 上,当我使用 shell或作为 shell 的su用户时,我看到启动脚本有不同的行为,尽管事实表明/bin/sh/bin/bash/bin/sh/bin/bash

我已经为用户设置了以下脚本:

/home/my_user/.profile

echo Hello from .profile

/home/my_user/.bash_profile

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

echo Hello from .bash_profile

/home/my_user/.bashrc

# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions
echo Hello from .bashrc

现在,当我su指定时/bin/bash,我得到以下输出。

[batwad@hellodave ~]$ sudo su -s /bin/bash my_user
Hello from .bashrc
[my_user@hellodave batwad]$

.bash_profile这是没有被处决的意思吗?毕竟,我没有看到“Hello from .bash_profile”

现在,当我su指定/bin/sh(无论如何链接到/bin/bash)时,我得到以下输出。

[batwad@hellodave ~]$ sudo su -s /bin/sh my_user
sh-4.2$

没有回声和不同的 shell 提示符。是什么赋予了?

更新

根据 redseven 的回答,我尝试添加-l并得到了另一种行为!

[bawtad@hellodave ~]$ sudo su -l -s /bin/sh my_user
Last login: Thu Aug 16 11:44:38 UTC 2018 on pts/0
Hello from .profile
-sh-4.2$

.profile这次用的就是这个!请注意,第一次尝试时并未出现“上次登录”部分。

答案1

我遇到了同样的问题Ubuntu 20.04.3,那是因为里面有这些行~/.bashrc

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

我的解决方案是将重要的命令移到~/.bashrc该块之前(基本上是加载 nvm 和 node.js 所需的行)。

答案2

如果您想在正常登录后使用所有设置,则最好使用su -l(或简单)选项:-

曼苏:

       -, -l, --login
       Provide an environment similar to what the user would expect had the user logged in
       directly.

使用该-l选项,您的 ~./bash_profile 将被使用(以及您的 .bashrc,如果它包含在您的 .bash_profile 中),否则您的 shell 不是登录 shell,只会使用 ~/.bashrc 。

仅当您的 shell 是 bash 时,这些才是正确的。如果您有不同的默认 shell 或使用 -s 选项指定不同的 shell,那么这完全取决于该 shell 的工作方式(可能使用或忽略 bash 设置)。即使 /bin/sh 是 bash 二进制文件的符号链接,它也是一个不同的 shell,二进制文件会检测您启动它的方式并启动不同的 shell,而不是 bash。

答案3

您看到的行为差异是一个标准功能,以bash确保与普通标准 Bourne shell 环境完全兼容。

bash来自标准手册页(类型)的口/INVOCATION

如果使用 sh 名称调用 bash,它会尝试尽可能模仿 sh 历史版本的启动行为,同时也符合 POSIX 标准。

答案4

如果 bash 作为交互式非登录 shell 启动,它将搜索~/.bash_bashrc,来查找~/.bashrc特定于用户的配置和/etc/bash.bashrc系统范围的配置(请参阅 bash 手册页)。

但是,如果它作为交互式登录 shell 运行(可以通过附加 来完成--login),它首先会查找~/.profile~/.bash_profile(无论可用的内容..在您的情况下,它会命中,~/.profile因此不会费心读取~/.bash_profile)以进行用户特定的配置和/etc/profile用于系统范围的配置

如果您想获取这两个文件的源代码,请将其添加到您的 .bashrc 文件中

 if [ -f $HOME/.profile ]; then
     . /etc/profile
 fi

相关内容