这很令人尴尬,但是经过多年全职使用POSIX系统后,我仍然很难确定是否应该在.bashrc.profile或其他地方进行shell定制。更不用说一些特定于操作系统的配置文件了,例如.pam_environment。是的,我知道如何困惑文档并了解何时加载或不加载每个文件。我想知道的是,是否有人将如何确定将给定类型的自定义内容放入哪个文件的综合指南综合在一起。

评论

此问题不应标记为重复,原因是添加的问题中没有.profile。

回答:serverfault.com/q/261802/270464

#1 楼

TL; DR:


~/.bash_profile应该是非常简单的,只需加载.profile
.bashrc(按顺序)
~/.profile的内容不是特别的
与bash相关,例如环境变量(PATH和朋友)
~/.bashrc在交互式命令行中具有您想要的任何内容。
命令提示符,EDITOR变量,供我使用的bash别名

其他一些注意事项:


任何可用于图形应用程序或sh(或以b43调用的bash)可用的内容都必须位于sh
~/.profile输出任何内容
应仅用于登录shell的所有内容都应放在~/.bashrc
确保~/.profile不存在。


评论


+1,这使〜/ .profile可以为显式运行/ bin / sh的GDM / LightDM / LXDM之类的服务正确设置环境。

–user1686
2014年7月29日在6:15

我的.bashrc输出很多东西,您能对此发表评论吗?特别是,应将问候语输出放在哪里?

–卡利莫
14年7月29日在7:32

@Calimo:使其仅以交互方式输出内容。您可以使用[[$-== * i *]]进行测试,即在特殊的$-变量中查找'i'。当然,仅在将bash编译为以非交互方式读取.bashrc的系统上,它才是最重要的。 (也就是说,不是Debian,但不是Arch。)但是,当尝试使用sftp或scp或类似工具进行连接时,这通常是导致神秘错误消息的原因。

–user1686
2014年7月29日在11:20



现在我知道了-为什么.bash_login不存在?它有什么作用?

–tedder42
2014年7月30日下午0:17

@ tedder42:它与.bash_profile和.profile相同。但是bash只读取三分之一中的第一个。这意味着,如果您具有.bash_login,则.profile和.bash_profile都将被神秘地忽略。

–user1686
2014年7月30日在7:06

#2 楼

在过去的几年中,我浪费了很多时间,因此我对此进行了超过10分钟的研究。我不知道这是不是最好的布局,它只是在几乎所有情况下都能正常工作的布局。

要求:


~/.profile必须与任何/ bin / sh兼容-包括bash,dash,ksh以及发行版可能选择使用的其他任何版本。
环境变量必须放在两个控制台登录名都可以读取的文件中(即“ login” 'shell)和图形登录名(即GDM,LightDM或LXDM之类的显示管理器)。
同时拥有~/.profile~/.bash_profile毫无意义。如果缺少后者,bash会很乐意使用前者,并且可以通过检查$BASH$BASH_VERSION来保护bash特定的行。
*profile*rc之间的分隔是前者用于“登录”外壳,并且每次您打开终端窗口时使用后者。但是,“登录”模式下的bash不会获取~/.bashrc,因此~/.profile需要手动完成。

最简单的配置是:



有一个~/.profile可以设置所有环境变量(特定于bash的变量除外),也许打印一行或两行,然后如果由bash运行则输出~/.bashrc,否则坚持使用与sh兼容的语法。

export TZ="Europe/Paris"
export EDITOR="vim"
if [ "$BASH" ]; then
    . ~/.bashrc
fi
uptime



有一个~/.bashrc可以执行任何特定于外壳程序的设置,并通过检查交互模式来避免在Debian上破坏sftp之类的东西(其中bash编译时可以加载~/.bashrc即使对于非交互式外壳):

[[ $- == *i* ]] || return 0

PS1='\h \w $ '

start() { sudo service "" start; }




但是,还存在某些非交互式命令(例如ssh <host> ls)跳过的问题~/.profile,但是环境变量对他们非常有用。



某些发行版(例如Debian)编译其bash,并可以选择为此类非交互式登录来源~/.bashrc。在这种情况下,我发现将所有环境变量(export ...行)移动到单独的文件~/.environ并从.profile.bashrc都获取它很有用,并采取了保护措施以避免重复两次:

if ! [ "$PREFIX" ]; then   # or $EDITOR, or $TZ, or ...
    . ~/.environ           # generally any variable that .environ itself would set
fi



不幸的是,对于其他发行版(例如Arch),我找不到很好的解决方案。一种可能性是通过将以下内容放入~/.pam_environment中来使用(默认情况下启用的)pam_env PAM模块:

BASH_ENV=./.environ        # not a typo; it needs to be a path, but ~ won't work


然后,当然,将~/.environ更新为unset BASH_ENV。 br />


结论?贝壳是一种痛苦。环境变量很痛苦。特定于发行版的编译时选项是一个巨大的难题。

评论


最后一段+1,但我更喜欢从.bash_profile采购.profile和.bashrc并保持.profile干净。

–nyuszika7h
2014年7月29日在9:52

@ nyuszika7h:谢谢,我的.profile很干净。

–user1686
2014年7月29日在11:18

请注意,每次打开窗口时,注释re都与OSX相反

–毫米mmmm
2014年7月29日在12:20

“同时拥有〜/ .profile和〜/ .bash_profile毫无意义”:我不同意。有关原因,请参见丹的答案。

– rubenvb
2014年7月30日在7:25

@rubenvb您能引用相关部分吗?我认为只有一个.profile并使用条件保护bash特定部分是很好的。

–开尔文
15年3月3日在19:28

#3 楼

看看ShreevatsaR撰写的这篇优秀博客文章。这是摘录,但请转到博客文章,其中包括对“登录外壳”等术语的解释,流程图以及Zsh的类似表格。


对于Bash,他们工作如下。读取适当的列。执行A,然后执行B,然后执行C,依此类推。B1,B2,B3意味着它仅执行找到的那些文件中的第一个。


+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+


评论


很好重要的是要注意,通常/ etc / profile调用/etc/bash.bashrc,而〜/ .profile调用〜.bashrc。如此有效地,还为交互式登录执行了/etc/bash.bashrc和〜/ .bashrc。

– Wisbucky
17年9月22日在18:30

请注意,某些发行版似乎覆盖了该方案(带来了奇怪的后果)-参见例如我的错误报告给openuse在这里:bugzilla.opensuse.org/show_bug.cgi?id=1078124

–克里斯汀·赫里兹(Christian Herenz)
18年1月30日14:45



顺便说一句。至少使用bash时,通过/ bin / sh调用bash时,这些文件均未执行

–JepZ
19年4月9日在9:23

@JepZ是的,这就是第三栏“脚本”的解释。

– Flimm
19年4月9日在15:37

@Flimm好吧,“脚本”列描述了通过bash(例如/ bin / bash)启动非交互式脚本时发生的情况。但是,如果通过sh启动脚本(并且/ bin / sh是/ bin / bash的符号链接),则不会执行上述任何操作(甚至不执行BASH_ENV)。 bash手册页的相关段落可以通过搜索是否使用名称sh调用bash来找到。

–JepZ
19年4月9日在17:02



#4 楼

我为您提供“综合”指南:


.bash_profile.profile加载.bashrc(如果存在),使用例如
[ -r $HOME/.bashrc ] && source $HOME/.bashrc

将其他所有内容.bashrc
停止担心。
每四年左右,花十分钟研究这个问题,然后放弃并返回“不用担心”。


编辑:在“全面”中添加了恐吓引号,以防万一有人想相信它。 ;)

评论


同时拥有.bash_profile和.profile有点多余;您只需要后者。不过,您确实需要使其具有/ bin / sh-proof的功能:if [“ $ BASH”] && [-r〜/ .bashrc];然后 。 〜/ .bashrc; fi,因为有些程序(即gdm / lightdm)可以从/ bin / sh脚本中手动获取文件。这也意味着保存在.bashrc中的环境将无效。不得不为-1,因为您的“综合”准则在许多系统上均不起作用,正如我多次发现的困难方式。

–user1686
2014年7月29日在6:13



没问题,我很乐意付出-1来获得答案,这不仅是merely舌的“综合”,而且您当然也赢得了该头衔。

–机械鱼
14年7月29日在13:38

#5 楼

我放弃了尝试弄清楚这一点的想法,并制作了一个脚本(~/.shell-setup),我从所有其他脚本中提取了这个脚本。

这种方法要求~/.shell-setup具有两个功能:


仅运行一次,即使是反复采购(使用Include防护)
也不会产生任何不必要的输出(在输出正常时进行检测)

#1非常标准,尽管也许在shell脚本中使用不多。

#2比较棘手。这是我在bash中使用的方法:

if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
    echo "Hello user!" # ... etc
fi


不幸的是,我不记得我是怎么想到的,或者为什么检测交互式shell是不够的。

#6 楼

将所有内容放入.bashrc中,然后从.bashrc中获取.profile

从bash手册页(在OS X 10.9上)中:


登录shell启动,bash从〜/ .bashrc读取并执行命令(如果该文件存在)。使用--norc选项可以禁止这种情况。 --rcfile file选项将强制bash从文件而不是〜/ .bashrc中读取并执行命令。



上面的文字就是为什么所有内容都放在.bashrc中的原因。但是,在处理登录shell时会有一些不同的行为。再次引用手册页:


当bash作为交互式登录shell或通过--login选项作为非交互式shell调用时,它首先读取并执行命令从文件/ etc / profile中获取(如果该文件存在)。读取该文件后,它将按该顺序查找〜/ .bash_profile,〜/ .bash_login和〜/ .profile,并从存在且可读的第一个命令中读取并执行命令。启动外壳程序以禁止此行为时,可以使用--noprofile选项。


登录外壳程序将读取.profile,但不会读取.bashrc。复制.bashrc中的所有内容都是bad™,因此我们需要在.profile中提供它,以使行为保持一致。

但是,您不想无条件地从.bashrc中获取.profile。请查看评论和其他答案以获取更多详细信息。

评论


-1,请勿从.profile获取.bashrc。参见@DanRabinowitz的答案。

–nyuszika7h
2014年7月29日在9:46



至少不是无条件的。

–nyuszika7h
2014年7月29日在9:53

[-n“ $ BASH” -a -f〜/ .bashrc] &&。 〜/ .bashrc对于.profile来说是一个很好的选择。

–John WH Smith
2014年7月29日上午10:55

@ nyuszika7h,为什么不呢?每个人似乎都建议这样做。

–起搏器
17年11月2日,13:36