登录和非登录shell定义为:
su - $USER # will give you a login shell
bash # will give you a non-login shell
/etc/profile 不会被非登录 shell 调用,例如当您启动 konsole (kde) 时。/etc/profile 只会被登录 shell 调用。
这是为什么?请解释一下,因为我想知道其中的原理。
答案1
/etc/profile
仅在登录 shell 中被调用,因为这是它的特定用途。
如果你想要一个命令在交互式 shell 中运行,那么不是登录 shell,并且您正在使用bash
,请将其放入~/.bashrc
或中/etc/bash.bashrc
。
“配置文件”的目的是包含只应为登录 shell 运行的命令。这些文件是:
/etc/profile
,由所有人运行Bourne 兼容 shell(包括bash
和dash
) 作为登录 shell 启动时。中的脚本
/etc/profile.d
。这是针对 Bourne 风格的 shell 的,但它并未编码到 shell 可执行文件本身中。相反,命令会调用
/etc/profile
它们。例如,在我的 Ubuntu 12.04 系统上,/etc/profile
包含以下几行:if [ -d /etc/profile.d ]; then for i in /etc/profile.d/*.sh; do if [ -r $i ]; then . $i fi done unset i fi
.profile
在用户的主目录中,当作为登录 shell 启动时由 Bourne 兼容 shell 运行(除非被覆盖,请参见下文)。.bash_profile
或.bash_login
用户主目录中。除 之外的 shell 会忽略这些bash
。但如果.bash_profile
存在,则bash
运行它代替.profile
。如果.bash_profile
不存在但.bash_login
存在,则运行 that 而不是.profile
。.bash_profile
(但当或.bash_login
存在时,通常会写为 *明确调用.profile
。)shell 特定的好处轮廓文件的区别在于,它们可以包含仅对该 shell 有效的命令或语法。例如,我可以
[[
在.bash_profile
/中使用求值运算符.bash_login
,但如果我在 中使用它.profile
,然后以我的 shell 身份登录dash
,则会失败。
“profile”文件中应该包含什么
“配置文件”文件应包含只应在登录开始时运行一次的命令。(这包括图形登录,因为它们也以登录 shell 开始。)如果 shell 是交互式的,则运行它的用户可能已登录,因此它可能有一个祖先(启动了它,或者启动了启动它的东西,或者启动了那个,等等),它是登录 shell。
您可能只想运行一次命令,因为:
- 没有必要在每次登录时运行多次,因为这样效率很低,或者
- 每次登录时运行多次会产生不良结果。
作为第二种情况的示例,其中会出现不良结果,请考虑这些行,它们默认出现在每个用户的~/.profile
:
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
假设你通过 SSH 登录,运行了另一个 shell(例如,zsh
),在某个时候发现你想暂时返回bash
但保留你的环境(所以bash
在 中再次运行zsh
),然后运行一个像这样的程序mc
运行 shell 作为其界面的一部分。如果bin
存在于您的主文件夹中,并且您的用户名james
是PATH
最内层的 shell 是这样的:
/home/james/bin:/home/james/bin:/home/james/bin:/home/james/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
这是低效的,并且(更重要的是)使得很难理解其内容PATH
。
但这绝不是一场灾难。据我所知,如果每个交互式 shell 都提供“配置文件”,就不会发生什么可怕的事情,在默认配置中.然而,由于“配置文件”的目的是包含每次登录时只运行一次的命令,用户或管理员可以向配置文件添加命令必须仅在启动登录 shell 时运行。
在每个交互式 Shell 中运行的命令的位置
如果您正在使用bash
,则其中包含要在每个交互式 shell 中运行的命令文件:
/etc/bash.bashrc
.bashrc
在用户的主目录中。
这最常用于以下命令:
- 只影响它们运行的 shell 的环境——甚至不影响子 shell,或者
- 即使这不是登录 shell,也应该运行。
例如,无论是否bash
是登录 shell,通常都应启用命令行制表符补全。因此,这出现在~/.bashrc
:
if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
. /etc/bash_completion
fi
那里,1和2两者都适用:这不会延续到在该 shell 内运行的其他 shell,并且bash
即使我使用不同的 shell 登录,制表符补全也应该可以工作。
登录 Shell 和交互式非登录 Shell 的命令放置位置
如果你正在使用bash
并希望命令在登录 shell 和交互式 shell 中运行,但这些 shell 不是登录 shell,通常将其放入/etc/bash.bashrc
或~/.bashrc
。这是因为,默认情况下,/etc/profile
并~/.profile
明确运行它们。例如,~/.profile
具有:
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
source "$HOME/.bashrc"
fi
fi
(同样,的/etc/profile
来源。)/etc/bash.bashrc
bash
因此,当您启动交互式bash
shell(无论它是否是登录 shell)时,“profile”和“rc”文件都会运行。
在非交互式 Shell 中将命令放在何处运行
您可能不想为所有非交互式 shell 指定任何要运行的命令;它们会在每次运行脚本时运行(前提是该脚本由您配置为运行它们的 shell 运行)。
这可能会导致严重损坏。如果您要这样做,并且系统上除了您正在使用的管理员帐户之外没有其他管理员帐户,您可能需要创建一个;这样可以更轻松地修复错误。
在bash
“rc”文件实际上运行的是shell 是否是交互式的。然而,在顶部他们说:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
因此,如果您需要命令自动运行,即使在非交互式 shell 中也是如此,比如运行脚本的 shell,您可以添加命令前那些线。
启动登录 Shell
登录后会启动一个登录 shell。如果你想让此后启动的 shell 充当登录 shell,请使用标志-l
(代表升登录)。 例如:
这是启动登录 shell 的最佳方式(无需登录),除非你想以如下方式启动其他用户。然后,使用:
sudo -i
为了root
(sudo -s
用于非登录、交互式 root shell)sudo -u username -i
对于任何用户su - username
对于非root
用户(用于非登录、交互式 root shell)su username
什么是最初的登录 shell?
一个初始登录 shell和登录外壳。这个答案中提到“登录 shell”的地方都可以说“初始登录 shell”(本节除外,因为这一部分已经没有任何意义了)。
这个词的一个原因是初始登录 shell就是它登录外壳也有不同的用法——识别哪个程序用作登录时执行的 shell。这是登录外壳以前说:
进一步阅读
- “shell 的配置文件”在“Unix 外壳”(维基百科)
bash
手册页- 完整 bash 手册(GNU)