为什么没有为非登录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 (包括bashdash )运行。

  • /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。

您可能只想运行一次命令,因为:

  1. 没有理由每次登录运行多次,效率低下, 或者
  2. 它会产生不希望的结果,每次登录时运行一次以上。

作为第二种情况的例子,如果出现不良结果,请考虑这些行,默认情况下出现在每个用户的~/.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在用户的主目录中。

这最常用于命令

  1. 只影响它们运行的​​shell的环境 – 甚至不影响子shell, 或者
  2. 即使这不是登录shell也应该运行。

例如,通常应启用命令行选项卡完成,无论bash是否为登录shell。 所以这出现在~/.bashrc

 if [ -f /etc/bash_completion ] && ! shopt -oq posix; then . /etc/bash_completion fi 

在那里, 12都适用:这不会延续到在其中运行的其他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 for root (对于非登录的交互式root shell使用sudo -s
  • sudo -u username -i for any user
  • su - usernameroot用户的用户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)