.bashrc 和 .bash_profile 之间的区别

.bashrc 和 .bash_profile 之间的区别

.bashrc和之间有什么区别.bash_profile?我应该使用哪一个?

答案1

传统上,当您登录 Unix 系统时,系统会为您启动一个程序。该程序是一个 shell,即用于启动其他程序的程序。它是一个命令行 shell:您可以通过键入其名称来启动另一个程序。默认 shell 是 Bourne shell,~/.profile当它作为登录 shell 调用时,它会从中读取命令。

Bash 是一个类似 Bourne 的 shell。~/.bash_profile当它作为登录 shell 被调用时,它会读取命令,如果该文件不存在¹,它会尝试读取~/.profile

您可以随时直接调用 shell,例如通过在 GUI 环境中启动终端仿真器。如果 shell 不是登录 shell,它不会读取~/.profile。当您将 bash 作为交互式 shell(即不运行脚本)启动时,它会读取~/.bashrc(除非作为登录 shell 调用,否则它只会读取~/.bash_profile或 )~/.profile

所以:

  • ~/.profile是放置适用于整个会话的内容的地方,例如您登录时想要启动的程序(但不是图形程序,它们进入不同的文件)和环境变量定义。

  • ~/.bashrc是放置仅适用于 bash 本身的内容的地方,例如别名和函数定义、shell 选项和提示设置。(您也可以在此处放置键绑定,但对于 bash,它们通常放入~/.inputrc.)

  • ~/.bash_profile可以代替 来使用~/.profile,但它只能由 bash 读取,而不能由任何其他 shell 读取。(如果您希望初始化文件在多台计算机上工作,而您的登录 shell 并非在所有计算机上都是 bash,则这主要是一个问题。)~/.bashrc如果 shell 是交互式的,则将其包含在内是合乎逻辑的。我建议在 中包含以下内容~/.bash_profile

    if [ -r ~/.profile ]; then . ~/.profile; fi
    case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
    

在现代 unices 上,与 相关的复杂程度有所增加~/.profile。如果您在图形环境中登录(即,如果您输入密码的程序在图形模式下运行),则不会自动获得读取 的登录 shell ~/.profile。根据图形登录程序、您随后运行的窗口管理器或桌面环境以及您的发行版如何配置这些程序,您的~/.profile可能会或可能不会被读取。如果不是,通常还有另一个地方可以定义环境变量和登录时要启动的程序,但不幸的是没有标准位置。

请注意,您可能会看到一些建议,要么放入环境变量定义,~/.bashrc要么始终在终端中启动登录 shell。这两种想法都不是好主意。这两种想法最常见的问题是,您的环境变量只会在通过终端启动的程序中设置,而不会在直接通过图标、菜单或键盘快捷键启动的程序中设置。

¹为了完整性,根据要求:如果.bash_profile不存在,bash 也会尝试,.bash_login然后再回退到.profile。请随意忘记它的存在。

答案2

由此短文

根据 bash 手册页,.bash_profile 针对登录 shell 执行,而 .bashrc 针对交互式非登录 shell 执行。

什么是登录或非登录 shell?

当您通过控制台登录(例如:输入用户名和密码)时,无论是在启动时物理坐在机器旁,还是通过 ssh 远程登录:在初始命令提示符之前执行 .bash_profile 来配置内容。

但是,如果您已经登录到您的计算机并在 Gnome 或 KDE 内打开一个新的终端窗口(xterm),那么 .bashrc 会在窗口命令提示符之前执行。当您通过在终端中键入 /bin/bash 来启动新的 bash 实例时,也会运行 .bashrc。

答案3

在过去,伪 tty 不是伪的,实际上也不是打字的,UNIX 是通过调制解调器访问的,速度非常慢,你可以看到每个字母都打印到屏幕上,效率是最重要的。为了提高效率,你需要一个主登录窗口的概念,以及你实际工作时使用的其他窗口。在主窗口中,你会想要收到任何新邮件的通知,可能还会在后台运行其他程序。

为了支持这一点,shell.profile专门在“登录 shell”上获取一个文件。一旦会话设置完成,这将执行特殊操作。Bash 对此进行了一定程度的扩展,先查看 .bash_profile,然后再查看 .profile,这样您就可以将只用于 bash 的内容放入其中(这样它们就不会搞砸 Bourne shell 等,它们也会查看 .profile)。其他非登录 shell 只会获取 rc 文件 .bashrc(或 .kshrc 等)。

这现在有点不合时宜了。您登录到主 shell 的次数与登录到 GUI 窗口管理器的次数不同。主窗口与其他窗口没有任何区别。

我的建议是 - 不要担心这个差异,它基于使用 unix 的旧风格。消除文件中的差异。.bash_profile 的全部内容应该是:

[ -f $HOME/.bashrc ] && . $HOME/.bashrc

并将你实际想要设置的所有内容放入 .bashrc 中

请记住,.bashrc 适用于所有 shell,包括交互式和非交互式 shell。您可以通过将此代码放在 .bashrc 顶部附近来缩短非交互式 shell 的来源:

[[ $- != *i* ]] && return

答案4

对 /ETC/PROFILE 负责人的更好评论

基于 Flimm 上述出色的回答,我在我的 Debian 的开头插入了这条新评论/etc/profile(您可能需要根据您的发行版进行调整。)

#!/bin/bash     # /etc/profile
#version=1      # In vi/vim say  :set ts=4


# FOR ALL LOGINS:
#
#   FIRST RUN       /etc/profile (THIS)     FOR SYSTEM LOGIN,   e.g. PS1 and PATH ??.   It runs:
#                   /etc/bash.bashrc        FOR SYSTEM STARTUP                          profile might also run:
#                   /etc/profile.d/*.sh     FOR SYSTEM STARTUP
#
#   THEN  RUN    ~/.bash_profile            FOR USER   LOGIN.   e.g. colors.            It runs: 
#                          ~/.bashrc        FOR USER   STARTUP.                         it runs:
#                   /etc/bash.shared        FOR USER   STARTUP


# ELSE:
#
#   FIRST RUN       /etc/bash.bashrc        FOR SYSTEM STARTUP
#
#   THEN RUN               ~/.bashrc        FOR USER   STARTUP                          It runs:
#                   /etc/bash.shared        FOR USER   STARTUP



# From http://tristram.squarespace.com/home/2012/7/20/why-profile-bash_profile-and-bash_login.html
#
#   "bash allows two alternatives for .bash_profile  (to get bash user specifics when logging in):
#       ~/.bash_login   , derived from the C shell's             file  named .login,    and 
#       ~/.profile      , derived from the Bourne and Korn shell files named .profile. 
#
#     Only one of these three is read when you log in.  Read first one found in this order:
#       ~/.bash_profile     i.e. if this is found read it, or       <-- I have this: hwj
#       ~/.bash_login            if this is found read it, or
#       ~/.profile               if this is found read it, else fail.
#
#   One advantage of bash's ability to look for either synonym is that 
#       if you have been using sh (the Bourne shell) you can retain your .profile .
#
#       If you need to add bash-specific commands, you can put them in .bash_profile 
#           followed by the command source .profile. 
#
#   When you log in, all the bash-specific commands will be executed and 
#       then bash will source .profile, executing the remaining shared bash AND Bourne commands. 
#
#       If you decide to switch to using sh (the Bourne shell) you don't have 
#           to modify your existing files.
#
#
#   A similar approach was intended for .bash_login and the C shell .login, 
#       but due to differences in the basic syntax of the shells, this is not a good idea."



# For BASH:  Read down the appropriate column.  
#   Executes A, then B, then C.
#     Executes only the first found of B1, B2, B3.
#       For bash  A then sources (A)  and  B2 then sources (B2).
#
#
# +----------------------------------+-------+-----+------------+
# |                                  | Interactive | non-Inter. |
# |                                  |    shell    |  script    |
# +----------------------------------+-------+-----+------------+
# |                                  | login |    non-login     |
# +==================================+=======+=====+============+
# |                                  |       |     |            |
# | Runs first                       |       |     |            |
# |        ALL USERS (system)        |       |     |            |
# |                                  |       |     |            |
# +==================================+=======+=====+============+
# |/etc/profile       (all shells)   |   A   |     |            | (this file) set PS1, & then source the following:
# +----------------------------------+-------+-----+------------+
# | /etc/bash.bashrc   (bash only)   |  (A)  |  A  |            |          Better PS1 + command-not-found
# +----------------------------------+-------+-----+------------+
# | /etc/profile.d/bash_completion.sh|  (A)  |     |            |
# +----------------------------------+-------+-----+------------+
# | /etc/profile.d/vte-2.91.sh       |  (A)  |     |            | Virt. Terminal Emulator
# | /etc/profile.d/vte.sh            |  (A)  |     |            | 
# +----------------------------------+-------+-----+------------+
# |                                  |       |     |            |
# |BASH_ENV                          |       |     |     A      | not interactive script (only reads the environment)
# +==================================+=======+=====+============+
#
# +==================================+=======+=====+============+
# |                                  |       |     |            |
# | Runs second                      |       |     |            |
# |   SPECIFIC USER (root & howard)  |       |     |            |
# |                                  |       |     |            |
# +==================================+=======+=====+============+
# |~/.bash_profile    (bash only)    |   B1  |     |            | renamed /root/.profile and /home/howard/.bash_login to this
# +----------------------------------+-------+-----+------------+
# |~/.bash_login      (bash & csh)   |   B2  |     |            | (didn't exist) **
# +----------------------------------+-------+-----+------------+
# | ~/.bashrc          (bash only)   |  (B2) |  B  |            | 1) extends bash PS1 prompt to colorize: su=red, other_users=green
# |  . ~/bash.shared                 |       |     |            | 2) sources ~/bash.shared to load shared stuff
# +----------------------------------+-------+-----+------------+
# |~/.profile         (all shells)   |   B3  |     |            | (didn't exist - now a link to .bash_profile)  ????
# +----------------------------------+-------+-----+------------+
#
# +----------------------------------+-------+-----+------------+
# |~/.bash_logout                    |    C  |     |            | gets sourced when we log off
# +----------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-

以下是我/etc/profile剧本的其余部分

    # === Get debugging functions ==========================================================
    caller="/etc/profile"
    . /etc/bash.say.shared      # debugging primitives for bash_say function used below and $LS_COLORS var
    n=$(( n + 2 ))  #  indent
    
    # === Source stuff to setup a monitor ==================================================
    if [[ $- == *i* ]]; then        # 'himBHs', where i means interactive
        bash_say 'Interactive login.  Setting up monitor.'
        . /etc/bash.bashrc          # Set PATH, umask.  
                                    # If interactive also setup dircolors, shell options, chroot prompt, command-completion
    fi
    
    
    # === Source any profile extensions ====================================================
    bash_say ""
    bash_say "Sourcing any extensions..."
    n=$(( n + 2 ))  #  indent
    
        if [ -d /etc/profile.d ]; then
    
          for src_d in /etc/profile.d/*.sh; do
            if [ -r $src_d ]; then
              bash_say "Sourcing  $src_d"
              . $src_d
            fi
          done
          unset src_d
        fi
    n=$(( n - 2 ))  #  indent
    #bash_say "---Done sourcing extensions"
    
    
    #unset bash_say
    n=$(( n - 2 ))  # outdent
    bash_say ""

这里还有我包含的/etc/bash.say.shared带有缩进功能的文件,用于帮助我调试到底发生了什么:

# /etc/bash.say.shared

# # === BASH STARTUP UTILITIES ==============================================================================
# Sourced by both:  /etc/profile (login entry point)   and  /etc/bash.bashrc (terminal setup entry point)
#   $caller is the caller


# --- Utility functions to show indented status lines ------------------------------------------------
#if test "${BASH_SAY+word}"; then       # Don't reload if already defined before
#   was="already was ";
#else

    # --- ENABLED? --------------------------------------------------------------------
    # Set to 'true' to show debugging 'bash_say' messages when starting up bash
    export BASH_SAY=true
    export BASH_SAY=false


    # --- FUNCTIONS -------------------------------------------------------------------
    # Create spaces function, if not already defined
    spaces() { local count=$1; while (( count-- )) ; do echo -n " "; done;}     # Print n spaces

    bash_say() {
        # Only echo if enabled AND when there is a tty.  Don't echo status for SSH because it messes up remote scp command.
        if [ $BASH_SAY = 'true'  -a  -t 0 ]; then spaces $n; echo -e "$1 "; fi  #Comment in to debug    #can't get $0 to work
        : ;     #Dummy function filler for when above line is commented out
    }
    bash_say test

    bash_sourcing() { bash_say ""; bash_say "Sourcing $1"; }    # Use at top of files

    # Needed so others can use them
    export -f spaces
    export -f bash_say
    export -f bash_sourcing
#fi

bash_sourcing "$caller";
n=$(( n + 2 ))      #  indent
    bash_sourcing "/etc/bash.say.shared";
    n=$(( n + 2 ))  #  indent
        bash_say "Bash startup debugging:  ${was}enabled";
        unset was
n=$(( n - 4 ))      # outdent x2
bash_say "";        # line break

我认为值得注意的是 Debian 的/etc/profile默认源(包括)/etc/bash.bashrc(即/etc/bash.bashrc存在)。因此登录脚本会读取这两个/etc文件,而非登录脚本仅读取 bash.bashrc。

还要注意的是,/etc/bash.bashrc当它不是以交互方式运行时,设置为不执行任何操作。因此这两个文件仅适用于交互式脚本。

相关内容