bash shell 环境设置参考
2013-04-05 15:53:54 阿炯

相关的配置文件
/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,并从/etc/profile.d目录的配置文件中搜集shell的设置。

/etc/bashrc:为每一个运行bash shell的用户执行此文件,当bash shell被打开时,该文件被读取。

~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,它设置一些环境变量,执行用户的.bashrc文件。

~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该文件被读取。

~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件。


详述如下

1. profile文件

1.1 profile文件的作用
profile(/etc/profile),用于设置系统级的环境变量和启动程序,在这个文件下配置会对所有用户生效。当用户登录(login)时,文件会被执行,并从/etc/profile.d目录的配置文件中查找shell设置。

1.2 在profile中添加环境变量
一般不建议在/etc/profile文件中添加环境变量,因为在这个文件中添加的设置会对所有用户起作用。当需要添加时,我们可以按以方式添加。如添加一个HOST值为freeoa.net的环境变量:
export HOST=freeoa.net

添加时,可以在行尾使用;号,也可以不使用。一个变量名可以对应多个变量值,多个变量值使用:分隔。添加环境变量后,需要重新登录才能生效,也可以使用source命令强制立即生效:
source /etc/profile

查看是否生效可以使用echo命令:
$ echo $HOST
freeoa.net

2. bashrc文件

这个文件用于配置函数或别名。bashrc文件有两种级别:系统级的位于/etc/bashrc、用户级的~/.bashrc,两者分别会对所有用户和当前用户生效。bashrc文件只会对指定的shell类型起作用,bashrc只会被bash shell调用。

3. bash_profile文件
bash_profile只有单一用户有效,文件存储位于~/.bash_profile,该文件是一个用户级的设置,可以理解为某一个用户的profile目录下。这个文件同样也可以用于配置环境变量和启动程序,但只针对单个用户有效。与profile文件类似,bash_profile也会在用户登录(login)时生效,也可以用于设置环境变理。但与profile不同,bash_profile只会对当前用户生效。


个别用户
用户家目录/.bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.

用户家目录/.profile
# ~/.profile: executed by Bourne-compatible login shells.

全体用户
/etc/bash.bashrc
# System-wide .bashrc file for interactive bash(1) shells.

/etc/profile
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))

它们的差异在于:
1.bashrc
系统启动后就会自动运行。

2.profile
用户登录后才会运行。

3.进行设置后,可运用source bashrc命令更新bashrc;当然也可运用source profile命令更新profile。

通常我们修改bashrc,有些linux的发行版本不一定有profile这个文件。另外,/etc/profile中设定的变量(全局)的可以作用于任何用户,而~/.bashrc等中设定的变量(局部)只能继承/etc/profile中的变量,他们是"父子"关系。

~/.bash_profile 是交互式、login 方式进入 bash 运行的。

~/.bashrc 是交互式 non-login 方式进入 bash 运行的。

通常二者设置大致相同,所以通常前者会调用后者。

下面是用户环境变量文件的总结,更加简洁

/etc/profile, /etc/bashrc, .bash_profile和.bashrc的差别
 
用户登陆Linux操作系统的时候,"/etc/profile"、"~/.bash_profile"等配置文件会被自动执行。执行过程是这样的:登陆Linux系统时,首先启动"/etc/profile",然后启动用户目录下的"~/.bash_profile",如果"~/.bash_login"和"~/.profile"文件存在的时候也会在执行"~ /.bash_profile"后被依次调用。

/etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,并从/etc/profile.d目录的设置文件中搜集shell的设置;

/etc/bashrc:为每一个运行bash shell的用户执行此文件,当bash shell被打开时,该文件被读取;

~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件;

~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时及每次打开新的shell时,该文件被读取;

~/.bash_logout:当每次退出系统(退出bash shell)时,执行该文件;

/etc/profile是全局性的功能,其中设置的变量作用于所有用户,~/.bash_profile中设置的变量能继承/etc/profile中的变量并作用于用户。~/.bash_profile 是交互式、login 方式进入 bash 运行的;~/.bashrc 是交互式 non-login 方式进入 bash 运行的。

内置的最重要的5个变量
Bash中内置了PS1/PS2/PS3/PS4及PROMPT_COMMAND共5个变量,用于控制Bash shell中提示符的内容和格式,PS1/PS2/PS3/PS4及PROMPT_COMMAND的意义。
PS1 :命令行提示符
控制着终端中系统默认提示符的格式 (一般系统默认为'\u@\h:\w \$ ')。我们可以在PS1控制字符串使用Bash预定义的转义符号加入如:用户/当前路径/主机名等信息,还可以使用转义字符串控制提示符的颜色。
export PS1='\[\e[0;32m\][\u@\h \w \$]\[\e[m\]'

PS2 :延续命令行提示符
控制终端中命令延续行的格式,一般系统默认为单字符'>'。和PS1一样,可以使用字符/预定义转义字符/转义序列等进行定制。
export PS2='\[\e[0;32m\]~>\[\e[m\]'

PS3 :脚本中select语句提示符
控制shell中提示用户进行选择的提示符,一般系统默认为'#?'。

PS4 :调试模式下脚本命令提示符("set -x"提示所执行命令)
调试模式下脚本命令提示符,用以将命令和命令执行结果区分开。系统默认为'+'。同样,可以使用各种字符/预定义符号/转义控制序列去设置PS4,此外,系统还提供了两个可用于PS4的变量'$0'和'$LINENO',分别表示脚本名和当前行号。

PROMPT_COMMAND :Bash shell在显示PS1提示符前所执行的命令
export PROMPT_COMMAND="echo -n [$(date +%H:%M:%S)]"

In Bash, why is PROMPT_COMMAND set to something invisible?
/etc/bashrc sets PROMPT_COMMAND here:
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}"; echo -ne "\007"'

PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}"; echo -ne "\033\\"'

\033 is the octal code for the Esc (Escape) character, which is a good hint that the echoed strings in your PROMPT_COMMAND are terminal control sequences. Both sequences in your examples look like they set the terminal title to user@host:pwd.

The first case, xterm* sets the window name and icon title. For a detailed explanation, look at the list of xterm control sequences and scroll down until you find OSC P s; P t; ST under Operating System Controls (OSC is ESC ] and ST is ESC \).

PROMPT_COMMAND can contain a command that is executed before the new prompt is printed by bash (so before PS1 is evaluated).

使用不同颜色输出文字
在shell中,可以通过转义序列[<attr>;<fgcolor>;<bgcolor>m设置文字的显示属性(可选择分别或组合设置显示属性/前景色/背景色)。如果要还原字符显示方案(显示属性/前景色/背景色)为系统默认,可以使用'\e[m'完成。
attr控制文字的修饰效果(终端并一定全部支持)
0:默认; 1:加亮; 2:变暗; 4:下划线; 5:闪烁; 7:反色显示; 8:隐藏文字; 9:删除线

fgcolor控制文本颜色
30:黑色; 31:红色; 32:绿色; 33:黄色; 34:蓝色; 35:紫色; 36:青色; 37:白色

bgcolor控制文本颜色
40:黑色; 41:红色; 42:绿色; 43:黄色; 44:蓝色; 45:紫色; 46:青色; 47:白色

显示属性/前景色/背景色定义在不同的数值区间,这样作的好处是不用显示指明颜色的作用域,系统也会从颜色数值推断出用户想要设置的究竟是属性/前景色/背景色。例如,'\e[9;41m'是要设置显示属性和背景色,保持前景色不变;'\e34m'仅设置前景色。

下面的脚本演示了各种颜色组合的显示效果
#!/bin/bash
for attr in 0 1 2 4 5 7 8 9; do
 for fgcolor in 30 31 32 33 34 35 36 37; do
  for bgcolor in 40 41 42 43 44 45 46 47; do
   printf '\e[%s;%s;%sm %1s;%02s;%02s ' $attr $fgcolor $bgcolor $attr $fgcolor $bgcolor
  done
  printf '\e[0;37;40m\n'
 done
 printf '\n'
done

转义字符ESC的输入
shell中,如果想输入ESC(转义)字符,可以先按ctrl+v键后,再按下ESC键,系统会显示出'^['表示转义字符输入完成
echo命令中,使用-e选项允许转义字符后,可以输入'\033'或'\e'表示转义符ESC
printf命令中,直接使用'\033'即可表示转义符ESC

光标控制
同样,通过转义序列我们可以控制光标移动到指定位置:
转义序列     跳转位置
\033[(L);(C)H、\033[(L);(C)f     跳转至第L行第C列
\033[(N)A     光标向上移动n行
\033[(N)B     光标向下移动n行
\033[(N)C     光标向前移动n列
\033[(N)D     光标向后移动n列
\033[2J     清除屏幕并移动至(0,0)
\033[K     删除至行尾
\033[s     保存光标当前位置
\033[u     恢复光标至保存位置

Bash prompt customization-定制bash环境

After user login to the systems user environment variables initialized from various files like:
global system files /etc/profile or /etc/bashrc
user files ~/.bash_profile , ~/.bash_login , ~/.profile , ~/.bashrc or ~/.bash_logout

It is important to know that all users environment variable have a life time equal to the terminal session. When the terminal session is closed the user's variables including bash shell variables defined during a terminal session are emptied and a again redefined when new terminal session is created either via logo in shell or interactive shell. Lets define two variables to prove this statement.

Bash prompt special characters

Bash prompt can be customized by use of special characters. This table contains bash prompt special characters and its explanation.
Special character    Special character explanation
\a : an ASCII bell character (07)     
\d : the date in "Weekday Month Date" format (e.g., "Tue May 26")
\] : end a sequence of non-printing characters     
\e : an ASCII escape character (033)
\h : the hostname up to the first '.'     
\H : the hostname
\j : the number of jobs currently managed by the shell     
\l : the basename of the shell's terminal device name
\n : newline     
\r : carriage return
\s : the name of the shell, the basename of $0 (the portion following the final slash)     
\t : the current time in 24-hour HH:MM:SS format
\T : the current time in 12-hour HH:MM:SS format     
\@ : the current time in 12-hour am/pm format
\A : the current time in 24-hour HH:MM format     
\u : the username of the current user
\v : the version of bash (e.g., 2.00)     
\V : the release of bash, version + patchelvel (e.g., 2.00.0)
\w : the current working directory     
\W : the basename of the current working directory
\! : the history number of this command     
\# : the command number of this command
\$ : if the effective UID is 0, a #, otherwise a $     
\nnn : the character corresponding to the octal number nnn
\\ : a backslash     
\[ : begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
\D{format} : the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required

转义符号 意义
\a : 响铃(ASCII 0x07)
\d : 日期(格式:星期 月 日)
\D{format} : 以指定格式显示当前日期(格式字符串将传递给strftime()函数,若为空则使用本机标准格式)
\e : ESC,(ASCII 0x1B)
\h : 本机名称(从左至右直到遇到'.')
\H : 本机名称
\j : shell当前正在处理任务号
\l : shell终端设备基本名称
\n : 换行(ASCII 0x0A)
\r : 回车(ASCII 0x0D)
\s : shell名,$0的基本名
\t : 当前时间,24小时制,格式为HH:MM:SS
\T : 当前时间,12小时制,格式为HH:MM:SS
\@ : 当前时间,12小时制,格式为HH:MM am|pm
\A : 当前时间,24小时制,格式为HH:MM
\u : 当前用户名
\v : Bash版本
\V : Bash发行号(版本+补丁级别)
\w : 当前路径,$HOME将会被缩写为'~'
\W : 当前路径的基本名(最后一级文件夹),$HOME处理同上
\! : 当前命令的命令历史记录编号
\# : 当前命令的编号
\$ : 如果当前用户ID为0(超级用户),则显示'#';否则显示'$'
\nnn : 八进制数值nnn对应的ASCII字符
\\ : 反斜杠'\'
\[ : 标识不打印字符串的开始
\] : 标识不打印字符串的结束

参考:
http://www.linuxconfig.org/bash-prompt-basics
https://wiki.archlinux.org/index.php/Bash_(简体中文)