.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
当它不是以交互方式运行时,设置为不执行任何操作。因此这两个文件仅适用于交互式脚本。