操作系统: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。此来源 .profilegnome-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
如果您再次输入,这是一个非登录子 shellbash
。它.bashrc
不来源于.profile
。它直接继承$PATH
自-bash
bash
bash
如果您再次输入,这是另一个嵌套的非登录子 shell 。它与其他非登录子 shell 的功能相同。它继承$PATH
自-bash
bash
这是预期的行为。尝试更改它可能会导致出现错误,即出现重复条目$PATH
,导致文件过长。
$PATH
如果您确实希望在非登录 shell 中使用较短的原始代码,您可以添加一些代码来~/.bashrc
检测这种情况,然后解析并删除其中的内容$PATH
。