前面讲过Shell支持4中变量类型,而其中环境变量就是用来定义每一个用户的操作环境,变量作用域只对当前用户shell进程及其子shell生效,并且机器重启变量失效。如我们常用的PATH变量就是一个环境变量,但是我们发现PATH变量重来没有失效过啊,不管机器有没有重启。那是因为针对环境变量有特定的环境变量配置文件,每一次用户登录就会加载此配置文件,同理在此文件中的变量就会生效。环境变量配置文件中主要是定义对系统操作环境生效的系统默认环境变量。
Bash Shell默认变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$BASH #系统可执行二进制程序文件的路径; $LANG #系统使用的字符集; $SHELL #系统使用的shell; $USER #当前用户; $BASH_VERSION #Bash的版本信息; $HOSTNAME #本地主机名; $EUID #有效的用户ID; $UID #当前用户的ID号; $HOME #当前用户的家目录; $HOSTTYPE #主机架构类型,用来识别系统硬件; $MACHTYPE #平台类型,系统平台依赖的编译平台; $OSTYPE #系统类型; $OLDPWD #上次使用的目录; $PWD #当前目录; $PPID #当前程序父进程; $PS1 #主提示符,如[root@localhost ~]#; $PS2 #第二提示符,主要用于补充完全命令输入时的提示符; $PS3 #第三提示符,用于select命令中; $PS4 #第四提示符,当使用-X选项调用脚本时,显示的提示符,默认为+号; $SECONDS #当前脚本已经运行的时长; |
Bash Shell环境变量配置文件作用域
环境变量配置文件根据作用域的不同又分为全局配置文件和用户配置文件,如下介绍:
1 2 3 4 5 6 7 8 |
# 全局配置文件(对Linux所有用户生效); /etc/profile /etc/profile.d/*.sh /etc/bashrc # 用户配置文件(对当前用户生效,每个用户家目录都有以下两个文件); ~/.bash_profile ~/.bashrc |
我们常用的bash shell有几种模式,而针对每种模式都有不同的方式去顺序读取这些环境变量配置文件。
Bash Shell四种模式介绍
登录式Shell(login shell)
取得bash时需要完整的登入流程,就称为login shell,正常登陆某个终端,如:当系统启动时或你开启一个新的终端登录系统时,系统通过调用/bin/login程序处理登录并在 一个shell中显示命令行提示符,这个shell就是login shell;该shell程序可以是bash也可以是sh或csh,具体使用哪种shell可以在/etc/passwd中设置(/bin/login程 序读取该文件决定使用哪种Shell)。另外命令“su – USERNAME”(完全切换到另一个用户环境),属于登录式Shell。
非登录式Shell(non-login shell)
取得bash界面的方法不需要重复登入的动作。如:以X window登入Linux后,再以X的图形化界面启动命令终端,此时的命令终端并不需要再次输入用户名和密码,所以此时bash的环境就称为non-login shell。另外命令“su USERNAME”(半切换只切换不使用用户环境),属于非登录式Shell。
Interactive shell and non-interactive shell
interactive意为交互式,这也很好理解,interactive shell会有一个输入提示符,并且它的标准输入、输出和错误输出都会显示在控制台上。所以一般来说只要是需要用户交互的,即一个命令一个命令的输入的shell都是interactive shell。而如果无需用户交互,它便是non-interactive shell。通常来说如bash script.sh此类执行脚本的命令就会启动一个non-interactive shell,它不需要与用户进行交互,执行完后它便会退出创建的shell。
登录式Shell读取环境变量配置文件的顺序(原则是找到即终止)
登陆—>执行/etc/profile—>profile调用执行/etc/profile.d/*.sh—->profile执行~/.bash_profile—->执行~/.bashrc—>执行/etc/bashrc—>命令提示符
非登录式Shell读取环境变量配置文件的顺序(原则是找到即终止)
登陆—>执行~/.bashrc—->执行/etc/bashrc—->执行/etc/profile.d/*.sh—>命令提示符
为了更好的理清这几种模式,下面我们对一些典型的启动方式各属于什么模式进行一个总结:
1)登陆机器后的第一个Shell:属于login + interactive
2)新启动一个Shell进程,如运行bash:属于non-login + interactive
3)执行脚本,如bash script.sh:属于non-login + non-interactive
4)运行头部有如#!/usr/bin/env bash的可执行文件,如./executable:属于non-login + non-interactive
5)通过ssh登陆到远程主机:属于login + interactive
6)远程执行脚本,如ssh user@remote script.sh:属于non-login + non-interactive
7)远程执行脚本,同时请求控制台,如ssh user@remote -t ‘echo $PWD’:属于non-login + interactive
8)在图形化界面中打开终端:输入non-login + interactive
PS:你可能会遇到在本地对远程主机通过SSH执行脚本有些环境变量无法找到,那么问题就出在登录shell的模式不同所读取的配置文件不同的问题。
配置文件的作用
根据登录式Shell的启动顺序介绍这些这些文件的作用。
/etc/profile
它是系统整体的配置文件,该配置文件里包含很多重要的变量信息,每个用户登陆取得bash后一定会读取这个配置文件。如果你想要设定环境变量对所有用户起作用,就要在这个地方设置。大概内容如下:
1. USER变量设置。
2. LOGNAME变量设置。
3. MAIL变量设置。
4. PATH变量设置。
5. HOSTNAME变量设置。
6. HISTSIZE变量设置1000。
7. 然后使用export把以上所有变量声明成环境变量。
8. 管理员和普通用户的umask设置。
9. 调用/etc/profile.d/*.sh文件。
/etc/profile.d/*.sh
在这个目录下一般用户可以自定义一些脚本,系统默认也有一些脚本,如/etc/profile.d/lang.sh这个脚本,其中最重要的就是这个脚本调用了/etc/sysconfig/i18n这个文件,而这个文件中定义定义的就是系统的默认语言,如
1 2 3 |
[root@localhost ~]# cat /etc/sysconfig/i18n LANG="en_US.UTF-8" SYSFONT="latarcyrheb-sun16" |
~/.bash_profile
这个文件文件会先检查~/.bashrc是否存在,然后会执行export PATH这个变量。
~/.bashrc
这个文件中都是用来定义别名使用的,如果你要定义别名就可以放在这个文件中。
/etc/bashrc
这个文件定义了PS1变量,可以用来设定登录提示符等信息;设定本地变量,添加定义命令别名。并且特别针对非登录的Shell重新设定了一些变量,如PATH,PS1等。
注意:按照文件的启动顺序,基本上定义的所有变量都会生效,但是后面启动的文件中定义的变量会覆盖前面文件中定义的相同名称的变量。所以要想更好地设定一些变量和别名,就需要对这些文件的作用域以及非登录式Shell和登录式Shell各自应用哪些文件。
其他变量配置文件
~/.bash_logout
用户登出时使用的配置文件,默认这个文件是空的,如果你想在退出系统时做什么操作就可以在这个文件中定义,如果说退出登录时可以执行命令“history -c”清空历史命令。
~/.bash_history
这个文件是用来记录用户操作的历史命令的,默认HISTSIZE=1000定义在/etc/profile文件中,你可以把这个变量值改的大一点都行。但是注意这个文件中定义的历史命令跟你用history命令查看的可能不尽相同。因为文件中的都是磁盘上,而history查看的在内存中。
~/.viminfo
这个文件是用环境变量来定义你的vim使用时的一些状态,比如是否显示行数、高亮等。
~/.mysql_history
这个文件当你安装MySQL之后就会有,跟.bash_history作用一样,不同的是.mysql_history是用来记录SQL语句的。
Shell登录提示符
上面说过在/etc/bashrc文件中会设定PS1变量,下面看看PS1变量都设置了什么信息?
1 2 |
[root@localhost ~]# echo $PS1 [\u@\h \W]\$ |
\u:表示用户名。
\h:表示主机名。
\W:表示工作目录的基名。
\w:表示工作目录全名。
\$:表示管理员显示为#,普通用户显示为$。
Shell登录提示信息
我们每次登录系统时都会有提示信息,注意这个登录提示信息是针对本地终端tty{1-6}的,而并非类SSH登录。
1)本地终端提示信息默认在文件/etc/issue中,如:
1 2 3 |
[root@localhost ~]# cat /etc/issue CentOS release 6.4 (Final) Kernel \r on an \m |
转义符说明
1 2 3 4 5 6 7 8 9 |
\d:显示当前系统日期 \s:显示操作系统名称 \l:显示登录的终端号,这个比较常用 \m:显示硬件体系结构,如x86 \n:显示主机名 \o:显示域名 \r:显示内核版本号 \t:显示当前系统时间 \u:显示当前登录用户的序列号 |
2)远程终端提示信息默认在文件/etc/issue中,如:
1 2 3 |
[root@localhost ~]# cat /etc/issue.net CentOS release 6.4 (Final) Kernel \r on an \m |
既然有信息为什么默认SSH登录时不显示呢?那是因为在SSH服务中默认并没有开启限时信息。如果想显示信息可以在/etc/ssh/sshd_config文件中,把Banner none改为Banner /etc/issue.net即可,然后重启服务重新登录就会看到显示信息。但是你会发现“Kernel \r on an \m”这行字符原样显示并没有进行转义,原因是远程信息提示不支持转义符的使用,一般就是用来写一些警告信息的。
3)登陆后提示信息
上面说的不管是远程还是本地,显示的都是登陆前的提示信息,而也可以做到登陆成功后给出提示信息,就是在文件/etc/motd中定义,默认这个文件是空的,需要写上面直接定义即可。
PS:上面说的一系列提示信息,了解就好,生产服务器最好做到什么信息都不要提示,以免带来安全问题。就算写也是写在/etc/motd文件中,最好写一些警告信息。
umask说明
在Linux系统中,管理员和普通用户所创建的文件和目录之间的权限是不同的。而实现这个不同的命令就是umask。umask是系统用来控制文件和目录创建时的默认权限的,系统定义默认创建文件最高权限为666,目录最高权限为777。
查看系统默认umask设定
1 2 |
[root@localhost ~]# umask 0022 |
#第一位表示特殊权限
#第二位表示属主权限
#第三位表示属组权限
#第四位表示其他权限
我们知道了系统默认允许文件或目录创建时的最高权限,那么真正在创建一个文件时就是使用最高权限减去umask值,如666-022得到的就是你创建这个文件的权限644。如果想要执行权限必须手动添加,用来保证系统安全。
但是在创建文件或目录时虽然意义上是使用666-umask,可是不是使用666-022这样得到的,因为这样会有一个问题;如果umask设定为033,那么使用666-033=633。这样这个文件还是有执行权限,所以权限不能使用数字进行换算,而是使用字母。什么意思呢?就是把666换算为字母权限(rw-rw-rw-),然后把033换算为字母权限(—–wx-wx);然后用系统默认权限666(rw-rw-rw-)跟umask权限033(—–wx-wx)进行比较,只要umask中的权限出现在系统默认权限中都进行丢弃,那么得到最终权限为644(rw-r–r–)也就没有执行权限。
实例验证:
1 2 3 4 5 6 |
[root@localhost ~]# umask 0033 [root@localhost ~]# umask 0033 [root@localhost ~]# touch test.txt [root@localhost ~]# ll test.txt -rw-r--r--. 1 root root 0 Nov 16 17:31 test.txt |
注意:最后说明一下,虽然系统对于文件或目录的创建设定了最高权限,但是对于管理员和普通用户所使用的默认umask却不同,管理员的umask默认是0022;普通用户umask默认是0002。