为什么人们从 bashrc 获取 bash_profile,而不是相反?

为什么人们从 bashrc 获取 bash_profile,而不是相反?

听起来大多数终端仿真器默认不以登录方式运行本地会话,因此它们将加载 bashrc 而不是 bash_profile。那么为什么大多数人将所有内容都放在 bash_profile 中并让 bashrc 来获取它,而不是相反呢?“大多数人”是指我迄今为止见过的大多数人。也许它并不像我想象的那么普遍。

我们不应该把配置放在那里并让 bashrc 源 bash_profile,而应该把所有内容都放在 bashrc 中并让 bash_profile 源,这样不是更有意义,而且与 Linux 社区更一致吗?

我听说过 iTerm2 的好评,听起来就像这样,而且几乎所有其他终端仿真器(默认 OSX 终端除外)最终都会在我本地运行时加载 bashrc。这并不重要,只要一个源另一个,但我很困惑为什么首选 bash_profile 是标准?

小注释:我搞错了 iTerm2。它默认运行登录会话,就像 Terminal.app 一样,不过两个模拟器似乎都有一个选项可以让你改变它。

答案1

人们从 bashrc 中获取 bash_profile,而不是反过来根据当地惯例

一切观点我读过的关于如何配置启动文件的文章bash主要基于本地惯例。本地惯例通常不提及大局,因为它不谈论非登录、非交互的情况。有趣的是,我看过,但我很少看到有人cron在他们的所有讨论中提到为什么要将变量放在一个启动文件中而不是另一个启动文件中。事实上,我还没有听到一条评论说:“/bin/sh 的存在是有原因的。当以 /bin/sh 的形式调用时,Bash 会模拟原始的 Bourne shell。“首先,我稍微离题了一点,这种情况对于不仅以交互方式使用 shell 的人来说很重要,而且对于提供非交互式、非登录 (无人看管或者背景)cron 需要最少 shell 处理的脚本,即后台处理不需要彩色提示、命令历史和替换、正确定义的 $TERM 变量等的细节。

此外,关于cron,我通常看到的是人们创建最小搜索路径或完全限定调用程序,并且不知道如何处理未连接到终端的输出(即非交互式、非登录bashsh案例)cron。这通常是因为没有完全理解 shell 启动顺序,这导致用户以与本地启动文件中已建立的约定不一致或不一致的方式实现自己的启动文件/etc

详细地说,本地约定完成的设置在该特定安装和 shell 的文件中进行了布局/etc。如果检查任何 UNIX 安装的/etc文件(这些文件是作为典型启动序列的一部分调用的) ,那么人们应该以与这些启动文件bash中建立的约定互补的方式创建自己的启动。/etc

Linux 文档项目指出:

/etc/skel/ 每个新用户的默认文件都存储在此目录中。每次添加新用户时,这些骨架文件都会复制到其主目录中。一般系统会有:.alias、.bash_profile、.bashrc 和 .cshrc 文件。其他文件留给系统管理员。

虽然bash手册没有明确提到目录中常见的这些文件/etc/skel,但据我回忆,SunOS、Solaris、RedHat、Ubuntu、HP-UX、umips 和 Ultrix 都有/etc/skel文件可以作为用户 shell 启动文件的模板。OSX 显然没有 - 我现在正在使用 OSX 10.9.1。不幸的是,OSX 在如何按照惯例进行设置方面没有给你太多指导,但由于 OSX 是 BSD 衍生产品,我只是使用了另一个 BSD 衍生产品,并以此为模板制作了我自己的bash启动顺序,对其进行调整以适应 OSX 10.9.1/etc启动文件中使用的本地惯例。

在一条平行评论中提到的一个重要观点是,对于 OSX,惯例是将每个新终端作为交互式登录 shell 启动。这确实是 OSX 中的默认设置。只要安装的用户一致,此惯例就没有问题。 可以通过对终端的首选项进行以下更改来更改 OSX 上终端的默认行为,以符合其他 UNIX 发行版的 shell 启动约定,特别是更改设置,Shells open with:发出/usr/bin/login -f -l whmcclos bash -i命令:

在此处输入图片描述

有了这些背景或介绍,我将开始我最好的建议, 物有所值。

我最好的建议是:

检查 UNIX 发行版管理员已放置的文件。从以下位置开始(如果存在)。不要忘记使用该ls -a命令,因为有些文件以点开头。查看这些文件在启动过程中是如何使用的,并查看您自己的启动文件如何与它们交互:

/etc/bashrc
/etc/profile
/etc/skel/.bash_logout
/etc/skel/.bashrc
/etc/bash.bashrc
/etc/bash_completion

请参阅bash手册以了解调用和启动顺序。一切都安排得非常好。

除上述所有情况外,还有一个警告 - 这是我在 OSX 10.9.1 安装上所做的事情 - 其他 UNIX 发行版将会有所不同,但下面介绍的内容应该适用于大多数(如果不是全部) UNIX 发行版,但请使用其他 UNIX 发行版的约定作为指南,以根据您自己的目的定制以下内容:

。轮廓

# ~/.profile: executed by the command interpreter for login shells.

# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.  Note, however, that we will have a ~/.bash_profile and it
# will simply source this file as a matter of course.

# See /usr/share/doc/bash/examples/startup-files for examples.
# The files are located in the bash-doc package.

# From here on out, I basically set up my PATH, LD_LIBRARY_PATH, and anything else I'd like
# global to running programs and how those programs find their libraries.  This is shared by
# `cron`, so we really don't want interactive stuff, here.  Also, I setup my environments
# for brew, macports, and fink here, essentially with setting PATH, and invocation of those
# package initialization file as in:

# Brew and locally compiled stuff:
export PATH=/usr/local/bin:$PATH
export PATH=/usr/local/sbin:$PATH

# The following line puts gnu utilities without the prefix "g" in the path
# i.e. tar/gtar:
export PATH=$PATH:/usr/local/Cellar/coreutils/8.21/libexec/gnubin

# MacPorts shoves stuff in /opt, so to get at that stuff...
export PATH=/opt/local/bin:$PATH
export PATH=/opt/local/sbin:$PATH

# Set up for using Fink, which lives in /sw:
[ -e /sw/bin/init.sh ] && . /sw/bin/init.sh

# My stuff:
export PATH=~/perl:$PATH
export PATH=~/bin:$PATH
export PATH=.:$PATH

.bashrc

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

# From here on out, I put in things that are meaningful to interactive shells, like aliases,
# `shopt` invocations, HISTORY control, terminal characteristics, PROMPT, etc.

.bash_配置文件

# ~/.bash_profile: executed by the command interpreter for login shells.

# Because of this file's existence, neither ~/.bash_login nor ~/.profile
# will be sourced.

# See /usr/share/doc/bash/examples/startup-files for examples.
# The files are located in the bash-doc package.

# Because ~/.profile isn't invoked if this files exists,
# we must source ~/.profile to get its settings:
if [ -r ~/.profile ]; then . ~/.profile; fi

# The following sources ~/.bashrc in the interactive login case,
# because .bashrc isn't sourced for interactive login shells:
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

# I'm still trying to wrap my head about what to put here.  A suggestion
# would be to put all the `bash` prompt coloring sequence functions as
# described on http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/

这就是我的观点。请记住,我的示例已尝试通过启动文件展示控制路径,并避免任何特定站点的惯例可能施加的影响。

答案2

为什么我们首先要把所有内容都放在 bash_profile 中?

.profile 最初由 /bin/sh 使用,使用 .profile 可以实现向后兼容。

除非你使用 mac,否则所有内容都不会放在 bash_profile 中。它放在 bashrc 中

将所有内容放入 bashrc 中并让 bash_profile 提供其来源,这不是更有意义并且与 Linux 社区更加一致吗?

通常会将系统信息放入连接到机器时加载的 shell 中(正常运行时间、需要更新的软件包、CPU 温度等...)。如果 bashrc 包含 bash_profile,则每次打开新 shell 时您都会看到所有这些信息。

在 Unix 中:

.bash_profile 由登录 shell 加载
.bashrc 由交互式 shell 加载

除了 Mac,它会加载登录 shell每个新航站楼(是否互动)

其他资源

bashrc 和 bash-profile 之间的区别

环境变量在哪里指定

答案3

[...] 我很困惑为什么优先选择 bash_profile 是标准?

谁说这是标准?Bash 手册其本身对这个问题有这样的看法:

因此,通常你的 ~/.bash_profile 包含以下行

如果 [ -f ~/.bashrc ]; 则 . ~/.bashrc; fi

在任何特定于登录的初始化之后(或之前)。

相关内容