当前位置: 首页>>技术教程>>正文


为什么没有为非登录 shell调用/etc/profile?

, , ,

问题描述

登录和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(包括bashdash)运行。

  • /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_loginbash以外的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。

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

  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都发送了”profile”文件,那么在默认配置中不会发生任何可怕的事情。但是,由于”profile”文件的目的是包含每次登录只运行一次的命令,因此用户或管理员可以向只能在启动登录shell时运行的配置文件添加命令。

在哪里为每个交互式Shell运行命令

如果您使用的是bash,则会在每个交互式shell中运行要运行的命令的文件:

  • /etc/bash.bashrc

  • 用户主目录中的.bashrc

这最常用于命令

  1. 只影响它们运行的​​shell的环境 – 甚至不影响子shell,或者

  2. 即使这不是登录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。然后,使用:

  • 用于rootsudo -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的意思,用来说:

  • OpenBSD的默认登录shell是ksh;在Ubuntu中,它是bash。”

  • “您可以使用chsh change登录shell。”

进一步阅读

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/2055.html,未经允许,请勿转载。