问题描述
登录和non-login shell定义为:
su - $USER # will give you a login shell
bash # will give you a non-login shell
不为non-login shell调用/etc /profile,例如当您启动konsole(kde)时。 /etc /profile仅针对登录shell调用。
这是为什么?请解释一下,因为我想了解这个的基本原理。
最佳解决办法
仅为登录shell调用/etc/profile
,因为这是其特定用途。
如果要为非登录shell的交互式shell运行命令,并且您正在使用bash
,请将其放在~/.bashrc
或/etc/bash.bashrc
中。
“profile”文件的目的是包含仅应为登录shell运行的命令。这些文件是:
-
/etc/profile
,作为登录shell启动时,由所有Bourne-compatible shells(包括bash
和dash
)运行。 -
/etc/profile.d
中的脚本。这适用于Bourne-style 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-compatible shell运行(除非被覆盖,请参见下文)。 -
用户主目录中的
.bash_profile
或.bash_login
。bash
以外的shell会忽略它们。但如果存在.bash_profile
,则bash
运行它而不是.profile
。如果不存在.bash_profile
但存在.bash_login
,则运行.profile
而不是.profile
。 (但是,.bash_profile
或.bash_login
存在时,通常会被写入以便*显式调用.profile
。)shell-specific配置文件的优点是它们可以包含仅对该shell有效的命令或语法。例如,我可以在.bash_profile
/.bash_login
中使用[[
评估运算符,但如果我在.profile
中使用它,然后使用dash
作为我的shell登录,它将失败。
在”profile”文件中应该怎么做
“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都发送了”profile”文件,那么在默认配置中不会发生任何可怕的事情。但是,由于”profile”文件的目的是包含每次登录只运行一次的命令,因此用户或管理员可以向只能在启动登录shell时运行的配置文件添加命令。
在哪里为每个交互式Shell运行命令
如果您使用的是bash
,则会在每个交互式shell中运行要运行的命令的文件:
-
/etc/bash.bashrc
-
用户主目录中的
.bashrc
。
这最常用于命令
-
只影响它们运行的shell的环境 – 甚至不影响子shell,或者
-
即使这不是登录shell也应该运行。
例如,通常应启用命令行 tab-completion,无论bash
是否为登录shell。所以这出现在~/.bashrc
中:
if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
. /etc/bash_completion
fi
在那里,1和2都适用:这不会延续到在其中运行的其他shell,并且即使我使用不同的shell登录,tab-completion也应该在bash
中工作。
在哪里放置登录壳和交互式non-Login壳的命令
如果您正在使用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
用于bash
的/etc/bash.bashrc
。)
因此,当您启动交互式bash
shell(无论它是否为登录shell)时,”profile”和”rc”文件都会运行。
在non-Interactive Shell中放置命令的位置
您可能不希望为所有non-interactive shell指定任何命令来运行;它们将在每次运行脚本时运行(前提是脚本由您配置为运行它们的shell运行)。
这可能导致严重破损。如果你要这样做,除了你正在使用的系统之外,系统上没有管理员帐户,你可能想创建一个;这可以更容易修复错误。
在bash
中,无论shell是否为交互式,”rc”文件实际上都会运行。然而,在顶部,他们说:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
因此,如果您需要命令甚至在运行执行脚本的non-interactive shell中自动运行,您可以在这些行之前添加命令。
启动登录Shell
登录会启动登录shell。如果您希望在此之后启动的shell充当登录shell,请使用-l
标志(代表登录)启动它。例如:
-
sh -l
-
bash -l
-
pdksh -l
这是启动登录shell(无需登录)的最佳方式,除非您想以另一个用户身份启动登录shell。然后,使用:
-
用于
root
的sudo -i
(使用sudo -s
用于non-login,交互式根壳) -
sudo -u username -i
适用于任何用户 -
用于非
root
用户的su - username
(使用su username
用于non-login,交互式根壳)
什么是初始登录shell?
初始登录shell与登录shell相同。无论如何,这个答案都说”login shell”它可以说是“初始登录shell”(本节除外,它已经有了明确的意义)。
术语初始登录shell的一个原因是登录shell也用于不同的意义 – 用于标识哪个程序用作登录执行的shell。这是登录shell的意思,用来说:
进一步阅读
-
“Unix shell”(维基百科)中的“shell配置文件”
-
bash
联机帮助页