我正在尝试在运行 lucid 的机器上调试 shell 环境问题。
root 和 user 在 /etc/passwd 中都有 /bin/bash 作为他们的 shell 当我使用“sudo su - user”时,我的 PATH 包括以下目录:/usr/local/rvm/rubies/ruby-1.9.3-p194/bin/ruby 当我“ssh user@machine”时它有:/usr/local/rvm/rubies/ruby-1.9.2-p290/bin/ruby
现在,这里可能有许多特定于 ruby/rvm 的答案——这不是我要找的,我想了解的是一般问题,即在哪里查找设置路径的内容。我知道 /etc/profile 会被执行,但它在两种情况下都会被执行,所以我不确定问题是什么——是否还有其他一些文件也会在登录时加载——在第一种情况下,但在另一种情况下没有?/ 正在加载的任何其他可以设置 PATH 的内容?
因此,似乎在加载 /etc/profile 之前发生了一些事情。我在 /etc/profile 的第一行中回显了环境,在 ssh 的情况下,路径已经包含对 /usr/local/rvm/rubies/ruby-1.9.2-p290/bin 的引用——而在 sudo su - 的情况下则没有。似乎在 ssh 的情况下使用了 /etc/environment,但在 sudo su - 的情况下没有……
我最近发现的另一件事也与此相关,来自: 带连字符和不带连字符的“su”有什么区别?
执行 su 时将使用 /etc/login.defs 文件,并且 /etc/environment PATH 设置会被其中的 ENV_PATH 或 ENV_SUPATH 覆盖...
需要澄清的是,/etc/profile 用于登录 shell,但不用于非登录 shell - 因此,例如 sudo env 不会显示仅在 /etc/profile 中设置的变量
登录帐户时不会显示在 /etc/environment 中设置的变量
答案1
这可能是由于登录 shell 和交互式 shell 之间的差异造成的。请参阅这里以获得一个很好的总结。
系统读取的第一个文件是 来设置变量/etc/environment
。之后,读取哪些文件取决于 bash 的调用方式。当您 时ssh user@machine
,您启动一个登录外壳但当你su username
开始交互式、非登录 shell。Bash 将在每种情况下从不同的文件读取其初始化设置。以下内容来自 bash 手册页(重点是我的):
当 bash 作为交互式登录 shell 调用时,或者作为带有 --login 选项的非交互式 shell 调用时,它首先从文件 /etc/profile 读取并执行命令(如果该文件存在)。读取该文件后,它会按顺序查找 ~/.bash_profile、~/.bash_login 和 ~/.profile,并从第一个存在且可读的命令中读取并执行命令。启动 shell 时可以使用 --noprofile 选项来禁止此行为。
当启动非登录 shell 的交互式 shell 时, bash 从 /etc/bash.bashrc 和 ~/.bashrc 读取并执行命令, 如果这些文件存在。可以使用 --norc 选项来禁止。--rcfile 文件选项将强制 bash 从文件而不是 /etc/bash.bashrc 和 ~/.bashrc 读取并执行命令。
因此,bash 根据其调用读取不同的启动文件。查看您机器中这些文件的内容,您可能会发现$PATH
它们以不同的方式定义。
话虽如此,正如@mpy 在评论中正确指出的那样,sudo su - user
应该启动一个登录 shell。你是当然您正在使用的sudo su -
不是简单sudo su
的还是仅仅是su
?-
应该启动一个登录 shell,它应该读取与完全相同的启动文件ssh user
。