理解 bashrc 和 profile(转)
转自:https://wido.me/sunteya/understand-bashrc-and-profile/
在一般的 linux 或者 unix 系统中, 都可以通过编辑 bashrc 和 profile 来设置用户的工作环境, 很多文章对于 profile 和 bashrc 也都有使用, 但究竟每个文件都有什么作用和该如何使用呢?
首先我们来看系统中的这些文件, 一般的系统可能会有
1 |
|
而如果系统是 ubuntu 或者 debian 的话, 就不会有 /etc/bashrc
而会有 /etc/bash.bashrc
文件.
以上这些就是常用 profile 和 bashrc 文件了. 要理解这些文件之前还需要了解 Shell, Shell 的 login(登入) 和 interactive(交互式) 模式.
Shell 的模式
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='\u@\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='\u@\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
才行.
最后还可以参考下 https://github.com/sunteya/sot 项目, 这个项目是我目前自己使用的的 dot 系列文件的配置. 里面的 bashrc 和 profile 都是按照上述流程修改的.
理解 bashrc 和 profile(转)的更多相关文章
- 理解bashrc和profile[转载]
这儿有一篇文章不错 https://wido.me/sunteya/understand-bashrc-and-profile/ http://blog.csdn.net/luotuo44/artic ...
- 《学渣Linux笔记》——关于.bashrc与profile(涉及交互式与非交互式、登录与非登录shell)
<学渣Linux笔记>--关于.bashrc与profile(涉及交互式与非交互式.登录与非登录shell) 1.基本概念(个人理解) 交互式shell:等待用户输入,并执行相应操作的sh ...
- [转] - bashrc与profile的区别
bashrc与profile的区别 要搞清bashrc与profile的区别,首先要弄明白什么是交互式shell和非交互式shell,什么是login shell 和non-login shell. ...
- Linux bashrc和profile的用途和区别
导读 使用终端ssh登录Linux操作系统的控制台后,会出现一个提示符号(例如:#或~),在这个提示符号之后可以输入命令,Linux根据输入的命令会做回应,这一连串的动作是由一个所谓的Shell来做处 ...
- linux关于bashrc与profile的区别(转)
转载自:http://www.cnblogs.com/hongzg1982/articles/2101792.html bashrc与profile的区别 要搞清bashrc与profile的区别,首 ...
- linux中bashrc与profile的区别
bashrc与profile的区别 要搞清bashrc与profile的区别,首先要弄明白什么是交互式shell和非交互式shell,什么是login shell 和non-login shell. ...
- Linux基础知识之bashrc和profile的用途和区别
使用终端ssh登录Linux操作系统的控制台后,会出现一个提示符号(例如:#或~),在这个提示符号之后可以输入命令,Linux根据输入的命令会做回应,这一连串的动作是由一个所谓的Shell来做处理. ...
- bashrc和profile的用途和区别
使用终端登录Linux操作系统的控制台后,会出现一个提示符号(例如:#或~),在这个提示符号之后可以输入命令,Linux根据输入的命令会做回应,这一连串的动作是由一个所谓的Shell来做处理. She ...
- 【转】Linux中/etc/profile,/etc/bashrc,~/.profile,~/.bashrcd的区别
//因为在原文章中博主说以下内容是网友说的,所以我就只加个转了,找不到原作者 /etc/profile,/etc/bashrc 是系统全局环境变量设定 ~/.profile,~/.bashrc用户家目 ...
随机推荐
- yii2.0 面包屑的使用
yii2中面包屑是yii2自带的小部件,类似本网站的导航栏应该就是采用面包屑来完成的 例子如下,需要引入 yii\widgets\Breadcrumbs echo Breadcrumbs::widge ...
- 图片的 base64 编码
图片的 base64 编码就是将一幅图片编码成一串字符串,使用该字符串代替图像地址.我们所看到的网页上的图片,都是需要消耗一个 http 请求下载而来的:(所有才有了 csssprites 技术< ...
- 两个队列实现一个栈,剑指offer P59
public class StackByQueue { private LinkedList<String> queue1; private LinkedList<String> ...
- 如何判断Socket已经关闭
引子 前段时间我们的服务由于一台交换机网络出现故障,导致数据库连接不上,但是在数据库的连接超时参数设置不合理,connect timeout设置的过长,导致接口耗时增加.DB连接超时后线程未正常结束, ...
- 把Excel工作簿的每个工作表提取出来保存为新工作簿
平台:MS office 2010 任务:有个excel工作簿,其中有上百个工作表,要求把每一个工作表全部保存为新工作簿,如果一个一个复制出来太傻了,可以用excel自带的VB解决. 方法:打开工作簿 ...
- 谷歌Dremel即时数据分析解决方案
Hadoop技术已经无处不在.不管是好是坏,Hadoop已经成为大数据的代名词.短短几年间,Hadoop从一种边缘技术成为事实上的标准.看来,不仅现在Hadoop是企业大数据的标准,而且在未来,它的地 ...
- CodeForces 702E Analysis of Pathes in Functional Graph
倍增预处理. 先看一下这张图的结构,因为出度都是$1$,所以路径是唯一的,又因为每个点都有出度,所以必然有环,也就是一直可以走下去. 接下来我们需要记录一些值便于询问: 设$t[i][j]$表示从$i ...
- SVD分解技术详解
版权声明: 本文由LeftNotEasy发布于http://leftnoteasy.cnblogs.com, 本文可以被全部的转载或者部分使用,但请注明出处,如果有问题,请联系wheeleast@gm ...
- jQuery第三章
一.jQuery中的DOM操作 一般来说,DOM操作分为3个方面,即DOM Core核心.HTML-DOM和CSS-DOM 1.DOM Core JavaScript中的getElementById( ...
- XmlNode和XmlElement区别
今天在做ASP.NET操作XML文档的过程中,发现了两个类:XmlNode和XmlElement.这两个类的功能极其类似(因为我们一般都是在对Element节点进行操作).上网搜罗了半天,千篇一律的答 ...