.bashrc 中没有对源 .profile 或任何其他文件的交叉引用

.bashrc 中没有对源 .profile 或任何其他文件的交叉引用

操作系统:Ubuntu 桌面 22.04

我最初以用户 carl 的身份登录。我打开一个 shell 并回显 $0,我确认我处于非登录 shell 中。(“bash”,无破折号)但是当我回显 $PATH 时,我看到 $HOME/.local/bin 和 $HOME/bin 都是源,既未在 ~/.bashrc 中声明,也未在 /etc/environment 中声明。

答案来自此主题表示从登录用户继承。

因此我测试了一些东西:

    $ su - root
    $ echo $0
    > -bash
    $ echo $PATH
    > /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
    $ su carl
    $ echo $0
    > bash
    $ echo $PATH
    > /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
    $ su - carl
    $ echo $0
    > -bash
    $ echo $PATH
    > /home/carl/.local/bin:/home/carl/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
    $ su carl
    $ echo $0
    > bash
    $ echo $PATH
    > /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

在此示例中,以 root 身份登录,然后切换到非登录用户 shell 后,PATH 变量应如此。然后我检查以 carl 身份登录,然后以 carl 身份切换到非登录 shell 是否继承了登录 shell 变量,结果没有。

其他注意事项:

  • “以登录 shell 身份运行命令”未选中
  • .bashrc 中没有对源 .profile 或任何其他文件的交叉引用
  • 不存在 .bash_login 或 .bash_profile 文件
  • 重启没有任何变化

我正式失去猜测了,非常希望有位企鹅大师能启发我,让我能再次入睡。

答案1

.local/bin默认添加的是(~/.profile复制自/etc/skel/.profile):

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi

.profile是正确的更改位置PATH,而不是.bashrc

.bashrc 中没有对源 .profile 或任何其他文件的交叉引用

不,事实恰恰相反。.profile来源.bashrc

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

让我们回顾一下你的例子:

$ su - root
$ echo $0
-bash # This is a root login shell. It sources /root/.profile
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ su carl
$ echo $0
bash # This is a user non-login shell. It sources .bashrc not .profile
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ su - carl
$ echo $0
-bash # This is a user login shell. It sources .profile not .bashrc
$ echo $PATH
/home/carl/.local/bin:/home/carl/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ su carl
$ echo $0
bash # This is a user non-login shell. It sources .bashrc not .profile
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

如果我强制(不推荐)使用su登录而不通过登录 shell,我就无法获得$PATH我想要的正常功能:

home@daniel-desktop3:~$ su home
Password: 
home@daniel-desktop3:~$ echo $0 # Non-login shell. Didn't get .profile
bash
home@daniel-desktop3:~$ echo $PATH # Missing what I want
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
home@daniel-desktop3:~$ bash # Start nested shell
home@daniel-desktop3:~$ echo $0
bash
home@daniel-desktop3:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
home@daniel-desktop3:~$ exit # Exit nested shell
exit
home@daniel-desktop3:~$ exit # Exit su shell
exit

但是,如果我正常登录,应该$PATH将 设置为子 shell。当您通过或 GUIexport登录时,应该将 设置为设置。然后,此变量将从您的桌面环境的进程、终端仿真器以及在其中运行的 bash 继承下来。su - username.profile$PATH

home@daniel-desktop3:~$ su - home
Password: 
home@daniel-desktop3:~$ echo $0 # Login shell sources .profile
-bash
home@daniel-desktop3:~$ echo $PATH # I get the path I want
/home/home/.elan/bin:/home/home/bin:/home/home/.cargo/bin:/home/home/kde/src/kdesrc-build:/home/home/.cabal/bin:/home/home/.ghcup/bin:/home/home/.local/bin:/opt/rocm-6.0.0/bin:/home/home/.go/bin:/home/home/.nvm/versions/node/v21.6.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/home/.local/share/JetBrains/Toolbox/scripts
home@daniel-desktop3:~$ bash # Start a subshell
home@daniel-desktop3:~$ echo $0 # .bashrc is sourced again. .profile is NOT sourced. $PATH is INHERITED
bash
home@daniel-desktop3:~$ echo $PATH # I inherit $PATH like I want
/home/home/.elan/bin:/home/home/bin:/home/home/.cargo/bin:/home/home/kde/src/kdesrc-build:/home/home/.cabal/bin:/home/home/.ghcup/bin:/home/home/.local/bin:/opt/rocm-6.0.0/bin:/home/home/.go/bin:/home/home/.nvm/versions/node/v21.6.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/home/.local/share/JetBrains/Toolbox/scripts
home@daniel-desktop3:~$ exit # Exit nested non-login subshell
exit
home@daniel-desktop3:~$ exit # Exit login shell
logout

因此,在 GUI 登录中,以下是一个简化的视图(忽略systemd其间的细节和其他过程):

  • gdm3以 root 身份
    • gnome-session或另一个 DE。此来源 .profile
      • gnome-terminal. 不提供任何来源。继承$PATH
        • bash。这是您的非登录子 shell。它.bashrc不来源于 。它通过 gnome-terminal 从 gnome-session .profile继承$PATH
          • bash. 这是一个子 shell,如果你bash再次输入。执行与上面相同的操作

对于 SSH/su - username登录(也忽略 PAM 详细信息):

  • sshd以 root 身份
    • -bash这是您的登录 shell。此来源 .profile。它不会直接引用,.bashrc除非.profile它被指示
      • bash如果您再次输入,这是一个非登录子 shell bash。它.bashrc不来源于.profile。它直接继承$PATH-bash
        • bashbash如果您再次输入,这是另一个嵌套的非登录子 shell 。它与其他非登录子 shell 的功能相同。它继承$PATH-bashbash

这是预期的行为。尝试更改它可能会导致出现错误,即出现重复条目$PATH​​,导致文件过长。

$PATH如果您确实希望在非登录 shell 中使用较短的原始代码,您可以添加一些代码来~/.bashrc检测这种情况,然后解析并删除其中的内容$PATH

相关内容