/etc/bashrc和/etc/profile傻傻分不清楚?

导读 在一般的 linux 或者 unix 系统中, 都可以通过编辑 bashrc 和 profile来设置用户的工作环境, 很多文章对于 profile 和 bashrc 也都有使用, 但究竟每个文件都有什么作用和该如何使用呢?

首先我们来看系统中的这些文件, 一般的系统可能会有

/etc/profile
/etc/bashrc

~/.bashrc
~/.profile

而如果系统是 ubuntu 或者 debian 的话, 就不会有 /etc/bashrc 而会有 /etc/bash.bashrc 文件. 以上这些就是常用 profile 和 bashrc 文件了. 要理解这些文件之前还需要了解 Shell, Shell 的 login(登入) 和 interactive(交互式) 模式.

Shell 的分类

系统的 shell 有很多种, 比如 bash, sh, zsh 之类的, 如果要查看某一个用户使用的是什么 shell 可以通过 finger [USERNAME] 命令来查看. 我们这里只说 shell 是 bash 的情况, 因为如果是 sh 或者其他 shell 显然不会运行 bashrc 的.

login shell 和 no-login shell

“login shell” 代表用户登入, 比如使用 “su -“ 命令, 或者用 ssh 连接到某一个服务器上, 都会使用该用户默认 shell 启动 login shell 模式. 该模式下的 shell 会去自动执行 /etc/profile 和 ~/.profile 文件, 但不会执行任何的 bashrc 文件, 所以一般再 /etc/profile 或者 ~/.profile 里我们会手动去 source bashrc 文件. 而 no-login shell 的情况是我们在终端下直接输入 bash 或者 bash -c “CMD” 来启动的 shell. 该模式下是不会自动去运行任何的 profile 文件.

interactive shell 和 non-interactive shell

interactive shell 是交互式shell, 顾名思义就是用来和用户交互的, 提供了命令提示符可以输入命令. 该模式下会存在一个叫 PS1 的环境变量, 如果还不是 login shell 的则会去 source /etc/bash.bashrc 和 ~/.bashrc 文件 non-interactive shell 则一般是通过 bash -c “CMD” 来执行的bash.

该模式下不会执行任何的 rc 文件, 不过还存在一种特殊情况这个我之后详细讲述

在可能存在的模式组合中 RC 文件的执行

SSH login, sudo su - [USER] 或者 mac 下开启终端 ssh 登入和 su - 是典型的 interactive login shell, 所以会有 PS1 变量, 并且会执行

/etc/profile
~/.profile

在命令提示符状态下输入 bash 或者 ubuntu 默认设置下打开终端

这样开启的是 interactive no-login shell, 所以会有 PS1 变量, 只会执行

/etc/bash.bashrc
~/.bashrc

通过 bash -c “CMD” 或者 bash BASHFILE 命令执行的 shell

这些命令什么都不会执行, 也就是设置 PS1 变量, 不执行任何 RC 文件 最特殊! 通过 “ssh server CMD” 执行的命令 或 通过程序执行远程的命令

这是最特殊的一种模式, 理论上应该既是 非交互 也是 非登入的, 但是实际上他不会设置 PS1, 但是还会执行

/etc/bash.bashrc
bashrc

这里还有一点值得注意的是 /etc/bashrc 任何情况下都不会执行.

bashrc 和 profile 的区别

看了之前那么多种状态组合, 最关键的问题是, 究竟 bashrc 和 profile 有什么区别呢?

profile

其实看名字就能了解大概了, profile 是某个用户唯一的用来设置环境变量的地方, 因为用户可以有多个 shell 比如 bash, sh, zsh 之类的, 但像环境变量这种其实只需要在统一的一个地方初始化就可以了, 而这就是 profile.

bashrc

bashrc 也是看名字就知道, 是专门用来给 bash 做初始化的比如用来初始化 bash 的设置, bash 的代码补全, bash 的别名, bash 的颜色. 以此类推也就还会有 shrc, zshrc 这样的文件存在了, 只是 bash 太常用了而已. 期望的执行顺序 => 代表 在文件内部 source, 换行的 => 代表自身执行结束以后在 source, 同一行表示先 source 在执行自身

普通 login shell

/etc/profile
   => /etc/bash.bashrc

~/.profile
  => ~/.bashrc => /etc/bashrc

终端种直接运行 bash

/etc/bash.bashrc
~/.bashrc => /etc/bashrc
bash -c “CMD”
什么都不执行
ssh server “CMD”
/etc/bash.bashrc => /etc/profile
~/.bashrc => | /etc/bashrc => /etc/profile
             | ~/.profile

这里会有点小混乱, 因为既有 /etc/bash.bashrc 又有 /etc/bashrc, 其实是这样的 ubuntu 和 debian 有 /etc/bash.bashrc 文件但是没有 /etc/bashrc, 其他的系统基本都是只有 /etc/bashrc 没有 /etc/bash.bashrc.

最终修改

为了达到上述我们需要的执行流程, 那必须对系统的 rc 文件做修改. 我们拿 Ubuntu 举例 首先 我们编辑 /etc/profile 在文件头部加入

export system_profile_loaded=1

这样其他文件就可以根据 $system_profile_loaded 来判断是否已经载入过 profile, 接着我们可以看到

  unset i
fi

if [ "$PS1" ]; then
  if [ "$BASH" ]; then
    PS1=‘\[email protected]\h:\w\$ ‘
    if [ -f /etc/bash.bashrc ]; then
    . /etc/bash.bashrc
    fi
  else
    if [ "`id -u`" -eq 0 ]; then
      PS1=‘# ‘
    else
      PS1=‘$ ‘
    fi
  fi
fi

umask 022

按照我们刚才的方案, 应该是不管任何情况都应该在文件末尾去载入 bashrc, 所以我们修改成

  unset i
fi

umask 022

if [ "$BASH" ]; then
  if [ "$PS1" ]; then
    PS1=‘\[email protected]\h:\w\$ ‘
  fi

  if [ -f /etc/bash.bashrc ]; then
    . /etc/bash.bashrc
  fi
else
  if [ "`id -u`" -eq 0 ]; then
    PS1=‘# ‘
  else
    PS1=‘$ ‘
  fi
fi

当然也可以有其他该法,只要符合在文件末尾载入 bashrc 就可以了. 接着我们修改 /etc/bash.bashrc, 我们需要在文件头加入

[ -n "${system_bashrc_running}" ] && return
system_bashrc_running=1
[ -z "${system_profile_loaded}" ] && source /etc/profile
unset system_bashrc_running
system_bashrc_runned=1

其中 system_bashrc_running 这样的变量都是为了防止2次反复调用而加入的. 这样系统级别的 rc 文件基本修改好了, 最好还可以再修改一下本地的rc文件, 所以我们编辑 “~/.profile”, 发现起内容是

# ~/.profile: executed by Bourne-compatible login shells.

if [ -n "$BASH" ]; then
  if [ -f ~/.bashrc ]; then
    . ~/.bashrc
  fi
fi

mesg n

而按照上述的修改规则只需要替换成

export local_profile_loaded=1

if [ -n "$BASH" ]; then
  if [ -f ~/.bashrc ]; then
    . ~/.bashrc
  fi
fi

这样就始终再载入完 profile 以后去载入 bashrc 了, 接着我们像编辑 /etc/bash.bashrc 一样的去修改 ~/.bashrc, 文件头上加入

[ -n "${local_bashrc_running}" ] && return
local_bashrc_running=1
[ -r /etc/bashrc -a -z "${system_bashrc_runned}" ] && source /etc/bashrc
[ -r ~/.profile -a -z "${local_profile_loaded}" ] && source ~/.profile
unset local_bashrc_running

用来防止反复加载 profile, 并且这里需要特殊注明的是

[ -r /etc/bashrc -a -z "${system_bashrc_runned}" ] && source /etc/bashrc

/etc/bashrc 这个文件只有在 mac 之类的系统下才有, 所以 ubuntu 这里这行可以不加, 不过有判断是否存在所以加了也没关系. 到这里基本上就可以比较完美的解决不通的 shell 加载顺序问题了, 当然比如这个用户用的是 zsh 之类的也需要按照类型的原理来修改. 另外, 在用户目录下 可能会存在 ~/.bash_profile, ~/.bash_login 这样的文件, 但如果有这些文件 bash 就不会去载入 ~/.profile 了, 所以如果存在的话需要删除 这些文件并把内容合并进 ~/.profile 和 ~/.bashrc 才行.

原文来自:http://www.linuxprobe.com/diff-bashrcprofile.html

免费提供最新Linux技术教程书籍,为开源技术爱好者努力做得更多更好:http://www.linuxprobe.com/

时间: 2024-10-12 15:01:58

/etc/bashrc和/etc/profile傻傻分不清楚?的相关文章

低俗文章之傻傻分不清楚的IC和ID卡

声明: PS.正如影片"低俗喜剧"开头导演所警告:内容充满不雅用语.成人题材.歧视.色情性描写,因此,本文章与"低俗喜剧"一样被编订为比家长指引级别更高一级的专家指责类别,若未能接受以上内容--大家立即点击浏览器右上角的红色X(Linux以及OSX的请点击左上角的X). 本文作者(即本人:黑板)以及背后技术团队(RadioWar)并无任何恶意语咒骂.针对任何个人或团队,只为求戏说RFID,故此因本低俗文章而引起各位不安.不适.不快.甚至不举,本文作者以及其背后技术团

驳《低俗文章之傻傻分不清楚的IC和ID卡》:ID和IC之我见

我很认真看完了<低俗文章之傻傻分不清楚的IC和ID卡>这篇文章:http://www.freebuf.com/articles/wireless/9451.html 我可以直接表明,我就是对你发表的关于RFID的几篇帖子口气很不爽,既然你这篇文章中间主题是就事论事,我也就事论事一番. 1.ID卡就是大家常常说的低频卡 2.其厚度较为厚,并且只是只读,只保存一串唯一身份识别序列号 3.ID卡不存在任何其他的数据 这三个是你总结的对方的观点,反观你的本篇文章,其中你用大段的话来描述,低频卡不全是I

16、Cocos2dx 3.0游戏开发找小三之Node:父节点、子节点、傻傻分不清楚

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30476133 Cocos2d-x 采用了场景.层.精灵的层次结构来组织游戏元素, 与此同时,这个层次结构还对应了游戏的渲染层次,因此游戏元素可以组织成树形结构,称作渲染树. Cocos2d-x 把渲染树上的每一个游戏元素抽象为一个节点,即 Node. 一切游戏元素都继承自 Node,因此它们 都具有 Node 所提供的特性. Node 定义了一个可绘制

Web前端后端傻傻分不清,

1. Web前端后端傻傻分不清 原创 2016年12月25日 19:50:08 7178 0 2 前言 ??做C开发将近六年,基本上没有接触过web相关的东西,原来听别人说web相关的东西的时候也是分不太清楚到底哪个是前端哪个是后台,前端和后台又是怎么配合着工作的?经过各方法搜索,很多类似的疑问终于得以弄明白. ??使用html.Javascript写的是Web前端,它不用向服务器(比如apache.nginx.tomcat等)交互在浏览器端就执行完了,比如使用Javascript弹出一个警告框

谈一谈让人傻傻分不清的1G,2G,3G,4G……

浅谈让人傻傻分不清的1G,2G,3G,4G-- 虽然大学里学过计算机网络,平时也总是看网上不停的喷着1G,2G,3G,4G到底是啥,但总觉得隔靴搔痒,看不出其本质区别,我不想详解其中的又臭又长的关键技术,就从大家能看明白的概念上说一说这些不同代网络技术的区别. 先从概念和区别说起 1G:没啥好说的,估计是有了后来的2.3G,才想起称呼原来的为1G.1G采用FDMA(模拟和频分多址技术),可实现区域的移动性服务,代表是第一代模拟制式手机,大哥大,通话锁定在一定频率,使用可调频电台就可以窃听电话,保

JS魔法堂:属性、特性,傻傻分不清楚

一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; console.log(el.getAttribute('hello')); // IE67下输出test,其他浏览器输出null “搞毛啊?”,苦逼的Jser对着浏览器大呼一声.然后就用下面蹩脚的方式草草处理掉了. function getAttr(el, prop){ return el[prop] || el

基础挺重要的,以前堆和栈傻傻分不清楚,这下知道了

堆与栈在内存里是怎么分配的? 对于初学编程的人员来说,变量在内存中是分配在堆中还是在栈中,往往不甚明白,今天我来清晰简单的讲解下. 步骤/方法 1 ?当我们看到一个变量类型是已知的,就分配在栈里面,比如INT,Double等.其他未知的类型,比如自定义的类型,因为系统不知道需要多大,所以程序自己申请,这样就分配在堆里面. 2 值类型与引用类型的分配,如图: 3 简单来说,值类型是分配在栈里面,引用类型分配在堆里面. 那从内存的分配角度来看,是因为值类型,已经知道了类型的范围大小,可以进行有效分配

OCA,OCP,OCM傻傻分不清?

可能大家知道OCA.OCP.OCM的关系是一个比一个难考,一个比一个含金量高,但是你知道具体的考试科目.考试方式.就业形势区别吗?不知道的话这篇通俗易懂的文章会让你一目了然. 区别一:含金量 ■OCA:数据库专业人员踏上Oracle数据库认证之途的第一步 表示具备Oracle数据库管理的基础知识. ■OCP:数据库专业人员掌握Oracle专项技术的行业认可证明,证明持证者能够以最高效的方式建立和管理关键的Oracle数据库功能. ■OCM:针对在Oracle技术领域拥有多年实践经验,并且经过高级

jQuery、DOM对象傻傻分不清楚

初学jQuery时,经常分辨不清楚哪些是jQuery对象,哪些是DOM对象.这是十分不好的现象.必须明确区分何为jQuery对象.何为DOM对象,对于后续的学习.理解才更方便. 先从DOM对象开始,之后在谈谈jQuery对象(jq对象基于DOM对象). DOM.DOM对象 DOM(Document Object Model,文档对象模型),DOM是W3C的标准.定义了访问HTML和XML文档的标准. 文档对象模型是中立于平台和语言的接口,允许程序和脚本动态的访问和更新文档的内容.结构以及样式,更

ERP系统和MES系统,不要傻傻分不清

公司说最近要上一套erp系统,说让我比较一下,erp系统哪个好,还有mes系统,我们适合上哪个系统,其实我还真的不太懂,刚接触erp跟mes的时候,对于两者的概念总是傻傻分不清楚,总是觉得既然都是为企业的信息化做贡献,那区别又是在哪儿呢? 然后经过一系列的搜索,现在终于有了一些概念了. 好吧,细细说来,ERP系统以供应链管理为核心,以销售部门和采购部门为信息源头,以设备.人力等其它系统为基础,使信息流在ERP内部得到有效的传递和集成. 产线上的数据采集,产品在生产流程中的数据跟踪等这部分属于ME