为什么没有为非登录shell调用/ etc / profile?
登录和非登录shell定义为:
su - $USER # will give you a login shell bash # will give you a non-login shell
不为非登录shell调用/ etc / profile,例如当您启动konsole(kde)时。 / etc / profile仅针对登录shell调用。
这是为什么? 请解释一下,因为我想了解这个的基本原理。
/etc/profile
仅针对登录shell调用,因为这是其特定目的。
如果您希望为非登录shell的交互式shell运行命令,并且您正在使用bash
,请将其放在~/.bashrc
或/etc/bash.bashrc
。
“配置文件”文件的目的是包含应该仅为登录shell运行的命令。 这些文件是:
-
/etc/profile
,作为登录shell启动时,由所有与Bourne兼容的shell (包括bash
和dash
)运行。 -
/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
。 除了bash
之外,shell会忽略它们。 但是如果.bash_profile
存在,bash
运行它而不是.profile
。 如果.bash_profile
不存在但.bash_login
存在,则运行而不是.profile
。(但是
.bash_profile
或.bash_login
在存在时通常被编写为*显式调用.profile
。)特定于shell的配置文件的好处是它们可以包含仅对该shell有效的命令或语法。 例如,我可以使用
[[
.bash_profile
/.bash_login
[[
求值运算符],但如果我在.profile
使用它,然后使用dash
作为我的shell登录,它将失败。
什么应该进入“配置文件”文件
“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
但保留你的环境(所以在zsh
再次运行bash
),然后运行像mc
这样的程序运行shell作为其界面的一部分。 如果您的主文件夹中存在bin
并且您的用户名是james
,则最内层shell中的PATH
类似于:
/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,并且tab-completion应该在bash
工作,即使我使用不同的shell登录也是如此。
在哪里放置登录shell和交互式非登录Shell命令
如果您正在使用bash
并且希望命令在登录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 . "$HOME/.bashrc" fi fi
(同样, /etc/profile
来源/etc/bash.bashrc
用于bash
。)
因此,当您启动交互式bash
shell时,无论是否为登录shell,都会运行“profile”和“rc”文件。
在非交互式shell中运行命令的位置
您可能不希望为所有非交互式shell指定任何命令来运行; 它们将在每次运行脚本时运行(前提是脚本由您配置为运行它们的shell运行)。
这可能导致严重破损。 如果您要这样做,除了您正在使用的系统之外,系统上没有管理员帐户,您可能想要创建一个; 这可以更容易修复错误。
在bash
, 无论shell是否具有交互性,实际上都会运行“rc”文件。 然而,他们在顶部说:
# If not running interactively, don't do anything [ -z "$PS1" ] && return
因此,如果您需要在非交互式shell(例如运行执行脚本的shell)中自动运行命令,则可以在这些行之前添加命令。
启动登录Shell
登录会启动登录shell。 如果您希望在此之后启动的shell充当登录shell,请使用-l
标志启动它(代表l ogin )。 例如:
-
sh -l
-
bash -l
-
pdksh -l
这是启动登录shell(无需登录)的最佳方式,除非您想以另一个用户身份启动登录shell。 然后,使用:
-
sudo -i
forroot
(对于非登录的交互式root shell使用sudo -s
) -
sudo -u username -i
for any user -
su - username
非root
用户的用户su username
对于非登录的交互式root shell使用su username
)
什么是初始登录shell?
初始登录shell与登录shell相同。 到处都是这个答案说“登录shell”它可以说是“初始登录shell”(除了本节,它已经有了明确的意义)。
术语初始登录shell的一个原因是登录shell也用于不同的意义 – 用于标识哪个程序用作登录执行的shell。 这是登录shell的意思,用来说:
- “ OpenBSD的默认登录shell是
ksh
;在Ubuntu中,它是bash
。” - “您可以使用
chsh
更改登录shell。”
进一步阅读
- “ Unix shell”中的“shell 配置文件 ” (维基百科)
-
bash
页 - 完整的bash手册(GNU)