~/.bashrc /etc/bashrc /etc/profile三个文件的区别

hanyouqing
  • 778

起因是这样的:

公司新方案考虑使用docker, 看到有个进入容器的快捷命令是这样实现的

wget -P ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker;
echo "[ -f ~/.bashrc_docker ] && . ~/.bashrc_docker" >> ~/.bashrc; source ~/.bashrc;

公司服务器需要配置JAVA_HOME环境变量,每次都要手动处理,而且操作系统及JAVA版本可能不一样,于是乎按以上思路写了个~/.bashrc_customer

# get the real path of a soft link command. 
function read_link {
    [ "$1" == "" ] && echo "A command option should be supplied!"
    [ "$1" == "" ] && exit 1

    [ -x /bin/readlink ]  || sudo yum -y install coreutils
    [ -x /usr/bin/which ] || audo yum -y install which
    if [ ! -x /bin/readlink -o ! -x /usr/bin/which ]; then
        echo "Command 'readlink' or which not found and failed to install 'coreutils' or 'which' by 'sudo yum -y install'!"
        exit 1
    fi

    cmd=$(which $1)
    [ -L "$cmd" ] && cmd=$(readlink $cmd)
    [ -L "$cmd" ] && cmd=$(read_link $cmd)
    echo $cmd
}
# JAVA ENV
function java_home {
    java_bin=$(read_link java)
    java_home=$(read_link java|sed 's#/bin/java##g')

cat <<JAVA
# JAVA_ENV
export JAVA_HOME=$java_home
export PATH=\$PATH:\$JAVA_HOME/bin
export CLASSPATH=.:\$JAVA_HOME/jre/lib/rt.jar:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar
JAVA
}

grep bashrc_mruse ~/.bashrc||echo '[ -f ~/.bashrc_costomer ] && . ~/.bashrc_costomer ' >> ~/.bashrc

执行~/.bashrc后就可以通过java_home来获取JAVA所需要的环境变量
然后将输出内容加入/etc/profile,执行source /etc/profileJAVA_HOME等环境变量就生效了;

问题来了:

在此以后每次登陆服务器终端都会显示(期望时可以使用~/.bashrc_costomer中定义的内容,但是登陆后终端不显示这行代码):

[ -f ~/.bashrc_costomer ] && . ~/.bashrc_costomer

但是系统默认~/.bashrc里有这么一行,是不会显示的

if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

是不是因为我姿势不对,有没有那位能指点下。

系统使用的是CentOS,默认shellbash

现在知道系统启动后会自动执行(或加载)以下文件

~/.bashrc
/etc/bashrc
/etc/profile

也希望能系统讲下这三个文件的关系和区别。

回复
阅读 7k
2 个回答
✓ 已被采纳

其实打开里面的内容看看就大概知道了,简言之:

  • ~/.bashrc 是用户相关的终端的环境设置,通常打开一个新终端时,默认会load里面的设置,在这里的设置不影响其它人。如果一个服务器多个开发者使用,大家都需要有自己的sdk安装和设置,那么最好就是设置它。

  • /etc/bashrc 是系统全局针对终端环境的设置,修改了它,会影响所有用户的终端环境,这里一般配置终端如何与用户进行交互的增强功能等(比如sudo提示、命令找不到提示安装什么包等),新开的终端,已经load了这个配置,最后才load用户自己的 ~/.bashrc

  • /etc/profile 是系统全局针对终端环境的设置,它是login时最先被系统加载的,是它调用了/etc/bashrc,以及/etc/profile.d目录下的*.sh文件,如果有一个软件包,系统上只安装一份,供所有开发者使用,建议在/etc/profile.d下创建一个新的xxx.sh,配置环境变量。

不会显示是什么意思?不会执行吗?
倒着说吧,抄一段先

/etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。
/etc/bashrc: 为每一个运行bash shell的用户执行此文件。
~/.bashrc: 当登录时以及每次打开新的shell时,该该文件被执行。

其实,就是 /etc/profile 是你登录系统时候要默认执行的代码,/etc/bashrc,~/.bashrc是打开bash 的时候预先执行的代码,不同的是后者不同用户的~不同,也就是说执行的.bashrc不同。

其实你不明白的是 source 文件名 可简写为. 文件名命令,这句话的本质上相当于,你在当前的文件中的所有代码手动敲入当前的shell运行一遍。而文件名不比非要是上述文件。这个文件与上述文件的区别就是,上述文件会在登录/打开shell的时候默认执行。
echo "[ -f ~/.bashrc_costomer ] && . ~/.bashrc_costomer" >> .bashrc 写入到.bashrc 中,不是执行的意思。如果想要执行还要. .bashrc但是

其实这一句本身改成 [ -f ~/.bashrc_costomer ] && . ~/.bashrc_costomer 就是如果存在就加载的意思,为什么还要费劲的加入到.bashrc中,然后在重新加载.bashrc呢?
你们公司原本的意思应该是,当我需要下载一个新的 docker 就可以简单的执行者一句,同时修改了shell的配置和重新加载了这个配置,可问题是,后面的名字是固定的,加载另一个docker确定不会覆盖前面那个?而且也会导致这个文件越来越大,而且都是一样的内容

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏