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

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

这很尴尬,但在全职使用 POSIX 系统多年后,我仍然很难确定 shell 自定义应该放在.bashrc.profile还是其他地方。更不用说一些特定于操作系统的配置文件,例如.pam_environment

是的,我知道如何仔细阅读文档并了解每个文件何时加载或未加载。我想知道是否有人汇总了全面的指南,以决定将给定类型的自定义放入哪个文件中。

答案1

总结:

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

  • ~/.profile包含与 bash 不特别相关的内容,例如环境变量(PATH及其相关变量)

  • ~/.bashrc有你在交互式命令行中想要的一切。命令提示符、EDITOR变量、bash 别名供我使用

其他几点说明:

  • 任何对图形应用程序或 sh(或以 bash 形式调用)可用的东西sh都必须~/.profile

  • ~/.bashrc不能输出任何内容

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

  • 确保~/.bash_login不存在。

答案2

在过去的几年里,我浪费了很多时间,所以我研究了这个问题十多分钟。我不知道这是否是最好的布局,但它恰好在几乎所有情况下都能正常工作。

要求:

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

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

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

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

最簡單配置如下:

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

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

    [[ $- == *i* ]] || 返回 0
    
    PS1='\h \w \$'
    
    启动(){ sudo 服务“$1” 启动; }
    

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

  • 某些发行版(例如 Debian)在编译 bash 时会选择~/.bashrc为此类非交互式登录提供源代码。在这种情况下,我发现将所有环境变量(行export ...)移动到单独的文件 中很有用~/.environ,然后从中获取它两个都 .profile并且.bashrc,使用一个保护措施来避免重复执行:

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

    BASH_ENV=./.environ        # 不是拼写错误;它需要是一条路径,但是 ~ 不起作用
    

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


结论? Shell 很麻烦。环境变量很麻烦。特定于发行版的编译时选项是巨大真痛苦。

答案3

看看这个ShreevatsaR 的精彩博客文章。这里有一个摘录,但请转到博客文章,它包括“登录 shell”等术语的解释、流程图和 Zsh 的类似表格。

对于 Bash,它们的工作原理如下。阅读相应的列。执行 A,然后执行 B,然后执行 C,等等。B1、B2、B3 表示它只执行找到的第一个文件。

交互式登录 交互式非登录 脚本
/etc/profile A
/etc/bash.bashrc A
~/.bashrc
~/.bash_profile B1
~/.bash_login B2
~/.profile B3
BASH_ENV A
~/.bash_logout C

答案4

我放弃尝试解决这个问题并制作了一个脚本(~/.shell-setup),该脚本来自所有其他脚本。

这种方法需要~/.shell-setup具备两个特点:

  1. 即使多次获取,也只运行一次(使用包括警卫
  2. 不要生成任何不需要的输出(检测输出是否正常)

#1 是相当标准的,尽管在 shell 脚本中可能不怎么使用。

#2 比较棘手。以下是我在 bash 中使用的:

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

不幸的是,我不记得我是怎么想到这个的,也不记得为什么检测交互式 shell还不够。

相关内容