在 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