在 .bashrc、.profile、.bash_profile 等之间进行选择

Avd*_*vdi 235 unix environment-variables

这是尴尬的,但经过多年的使用POSIX系统充分的时间,我仍然有一个很难搞清楚,如果一个shell定制应该进去.bashrc.profile或者别的地方。更不用说一些特定于操作系统的配置文件,如.pam_environment.

是的,我知道如何通过文档拼图并了解每个文件何时加载或未加载。我想知道的是,是否有人对如何决定将给定类型的自定义放入哪个文件中的每个文件都汇总了全面的指导方针。

小智 269

特尔;博士:

  • ~/.bash_profile应该非常简单,只需加载.profile.bashrc(按此顺序)

  • ~/.profile有与 bash 没有特别关系的东西,例如环境变量(PATH和朋友)

  • ~/.bashrc在交互式命令行中拥有您想要的任何东西。EDITOR供我使用的命令提示符、变量、bash 别名

其他一些注意事项:

  • 任何应该可用于图形应用程序或可用于 sh(或 bash 调用为sh)的东西都必须在~/.profile

  • ~/.bashrc 不能输出任何东西

  • 任何应该只对登录 shell 可用的东西都应该进入 ~/.profile

  • 确保~/.bash_login不存在。

  • @Calimo:让它只在交互模式下输出东西。您可以使用 `[[ $- == *i* ]]` 来测试它,即在特殊的 `$-` 变量中查找 'i'。当然,只有在 bash 被编译为以非交互模式读取 `.bashrc` 的系统上,它首先很重要。(也就是说,Debian 而不是 Arch。)但是当尝试使用 `sftp` 或 `scp` 或类似工具进行连接时,这是一个经常导致神秘错误消息的原因。 (17认同)
  • 我的`.bashrc` 输出了很多东西,你能评论一下吗?特别是,我应该把问候输出放在哪里? (13认同)
  • @tedder42:它与`.bash_profile` 和`.profile` 的作用相同。但是 bash 只读取三个中的第一个。意思是,如果你有一个 `.bash_login`,那么 `.profile` 和 `.bash_profile` 都会被神秘地忽略。 (11认同)
  • 现在我必须知道 - 为什么 .bash_login 不存在?它有什么作用? (4认同)
  • +1,这允许`~/.profile` 为明确运行 /bin/sh 的 GDM/LightDM/LXDM 等服务正确设置环境。 (3认同)
  • 根据手册页和链接的重复问题,@grawity `bash` 将加载 `.bash_profile` 而不是 `.bash_login`,如果它们都存在的话。所以说`.bash_login` 会导致`.bash_profile` 被忽略是不准确的。 (2认同)

use*_*686 64

在过去的几年中,我有很多的时间可以浪费,所以我已经研究了这个多一点只需10分钟。我不知道这是否是最好的布局,它只是一种几乎在所有情况下都能正常工作的布局。

要求:

  • ~/.profile 必须与任何 /bin/sh 兼容——这包括 bash、dash、ksh,以及发行版可能选择使用的其他任何东西。

  • 环境变量必须放在控制台登录(即“登录”shell)和图形登录(即 GDM、LightDM 或 LXDM 等显示管理器)读取的文件中。

  • 同时拥有 ~/.profile和没有什么意义~/.bash_profile。如果缺少后者,bash 会很乐意使用前者,并且可以通过检查$BASH或来保护任何特定于 bash 的行$BASH_VERSION

  • *profile和之间的区别在于,*rc前者用于“登录”shell,后者用于每次打开终端窗口时。但是,“登录”模式下的 bash 没有 source ~/.bashrc,因此~/.profile需要手动执行。

最简单的配置是:

  • 有一个~/.profile设置所有环境变量(bash 特定的环境变量除外),可能打印一两行,~/.bashrc如果由 bash 运行,则源,否则坚持 sh 兼容的语法。

    出口 TZ="欧洲/巴黎"
    导出编辑器=“vim”
    如果 [ "$BASH" ]; 然后
        . ~/.bashrc
    菲
    正常运行时间
    
  • 有一个~/.bashrc执行任何特定于 shell 的设置,通过检查交互模式来保护以避免破坏sftpDebian 之类的东西(其中 bash 编译时带有选项,~/.bashrc即使对于非交互式 shell 也可以加载):

    [[ $- == *i* ]] || 返回 0
    
    PS1='\h \w \$ '
    
    开始(){ 须藤服务“$1”开始;}
    

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

  • 某些发行版(例如 Debian)编译他们的 bash 并选择~/.bashrc为此类非交互式登录提供源。在这种情况下,我发现它有用的所有环境变量(移动export ...线)到一个单独的文件,~/.environ以及从源代码这两者 .profile.bashrc与保护,以避免做两次:

    如果 ![“$前缀”]; 然后   # 或 $EDITOR,或 $TZ,或 ... 
        。~/.environ            # 通常任何 .environ 本身会设置的变量
  • 不幸的是,对于其他发行版(例如 Arch),我还没有找到很好的解决方案。一种可能性是使用(默认启用)pam_env PAM 模块,将以下内容放入~/.pam_environment

    BASH_ENV=./.environ         # 不是打字错误;它需要是一条路径,但是 ~ 行不通
    

    然后,当然,更新~/.environunset BASH_ENV.


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

  • 最后一段+1,但我更喜欢从`.bash_profile` 中获取`.profile` 和`.bashrc` 并保持`.profile` 干净。 (2认同)

Fli*_*imm 42

看看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      |           |      |
+----------------+-----------+-----------+------+
Run Code Online (Sandbox Code Playgroud)

  • @Flimm 那么,“脚本”列描述了当您通过 **bash** (例如 /bin/bash)启动非交互式脚本时会发生什么。但是,如果您通过 **sh** 启动脚本(并且 /bin/sh 是 /bin/bash 的符号链接),则以上内容都不会执行(甚至不会执行“BASH_ENV”)。 bash 手册页的相关段落可以通过搜索“If bash is invoked with the name sh”找到。 (2认同)

Mec*_*ish 24

我为您提供我的“全面”指南:

  • 制作.bash_profile.profile加载(.bashrc如果存在),使用例如 [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • 把其他的都放进去.bashrc
  • 别担心了。
  • 每四年左右,花十分钟研究这个问题,然后放弃并回到“不担心”。

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

  • 同时拥有`.bash_profile` 和`.profile` 有点多余;你只需要后者。不过,您确实需要使其/bin/sh-proof:`if [ "$BASH" ] &amp;&amp; [ -r ~/.bashrc ]; 然后 。~/.bashrc; fi`,因为有些程序(即 gdm/lightdm)从 /bin/sh 脚本手动获取文件。这也意味着保存在 `.bashrc` 中的环境将是无效的。不得不-1,因为您的“全面”指南在许多系统上都不起作用,因为我已经多次发现困难的方法。 (3认同)