第四章 shell与环境变量
4.1 shell概述
4.1.1 编译器
从根本上讲,一台计算机由CPU、内存、主板、声卡、显卡等硬件组成,完整的硬件构成了所谓的“裸机”。在安装操作系统之前,计算机无法正常使用。Windows和Linux都是操作系统的例子。
在操作系统安装完成后,用户可以安装各种应用软件,例如QQ和迅雷。这些软件通常使用Java、C#、C++等高级编程语言编写。然而,计算机硬件只能理解二进制代码,即所谓的“机器语言程序”。因此,需要一个工具将高级语言程序翻译成机器语言程序,并将硬件执行的二进制结果转换回高级语言程序状态。这个工具被称为“命令解释器”或“编译器”。
从工作原理来看,操作系统通常由系统内核和编译器两部分组成。系统内核负责管理和调度硬件,如控制磁盘读取数据到内存中,再由CPU执行。而编译器负责将外部程序翻译成内核可识别的程序状态,驱动硬件执行。具体结构请参考以下图示:
由于系统内核的不同,不同的操作系统也使用不同的编译器,因此一种操作系统下的程序无法在其他操作系统上运行。例如,Windows程序无法在Linux上运行。
值得一提的是,为了使同一程序可以在不同操作系统上运行,Java推出了独立的编译器JDK。在不同操作系统上安装相应版本的JDK后,同一Java程序就可以在不同操作系统上运行了。因此,Java被认为解决了程序的跨平台问题。
Windows系统有自己的编译器(通常是.NetFramework系列),而Linux也有自己的独立编译器,称为SHELL。
4.1.2 shell简介
shell是Linux内核的一个外壳,为用户和内核之间的交互提供接口。当用户向操作系统发出指令时,实际上是通过shell进行解释和处理,然后由内核执行相应的操作。系统的响应和输出信息也由shell处理后显示在用户屏幕上。
shell有多种版本,如bash、sh、ksh、csh等,RHEL系列默认使用bash。
4.2 命令分类
4.2.1 命令执行原理
我们先来对比一下Windows系统。在Windows的开始=>运行界面中输入命令,例如cmd(命令窗口)、mspaint(画图)、calc(计算器)等。
当在运行中输入命令时,Windows实际上是在c:\windows\system32\文件夹中查找相应的可执行程序并运行。具体如下图所示:
同样,Linux中的命令,如ls、cp、mv等,也都有对应的可执行程序。我们可以通过以下命令查看:
whereis ls —查看指定命令对应的可执行程序和帮助文档的位置。如图
which ls —查看指定命令的别名形态及可执行程序的位置
其中whereis显示结果中/usr/bin/ls是命令对应的可执行程序,/usr/share/man下的文件是ls对应的帮助文档;which结果中的alias行显示的是命令的别名。
注:关于命令别名,我们将在后续内容中详细介绍。
虽然whereis可以查看到命令的可执行程序,但有些命令却查不到,例如exit。
具体原因请阅读下节内容。
4.2.2 命令分类
在Linux中,根据命令程序所在位置的不同,系统命令被分为两大类:内建命令和外部命令。具体如下:
内建命令 —又称内置命令
集成在系统shell中,因此系统外部没有对应的可执行程序。
内置命令可以直接运行,无需shell编译。
内置命令使用whereis时不可查。
help —查看所有内置命令。
外部命令
位于系统shell之外,有对应的可执行程序。
运行外部命令时,会被shell编译后再交由内核执行。
外部命令使用whereis可查。
内外部命令的应用虽然目前看起来区别不大,但在未来的工作中,对于内外部命令的不同操作会产生很大的差异。特别是在计划任务、sudo授权、shell编程等章节中,我们将使用到外部命令的概念。
4.3 环境变量
4.3.1 环境变量的功能
我们还是从Windows系统开始讲起。前面提到,当我们在开始=>运行中输入命令时,系统会在c:\windows\system32\文件夹中查找相应的程序。但是,读者可能会有疑问:为什么Windows会在这个文件夹中查找,还有没有其他文件夹系统也会去查找呢?带着这个问题,我们进行如下操作:
右键“计算机”=>属性=>左侧“高级系统设置”=>下侧“环境变量”
显示的就是Windows的环境变量信息,如图所示:
在“系统变量”区域中,可以看到path,这就是Windows的一个环境变量。path的功能是指定Windows在哪些文件夹中查找命令的可执行程序,相邻两项之间用;(分号)分隔。我们可以通过点击“编辑”按钮查看具体内容。
从这个例子可以看出,环境变量是表示系统中某一项工作状态的变量。我们可以这样理解:系统桌面的分辨率、桌面图标的字体大小、系统声音大小都是由变量记录指定的。因此,环境变量是任何系统都不可或缺的配置记录工具。
在Linux中,也有许多环境变量来帮助系统记录各种配置。我们可以通过以下命令查看:
env —查看系统环境变量
set —查看所有环境变量
系统中常用的环境变量如下表所示:
环境变量 说明 LOGNAME 登陆名,也就是账户名 PATH 命令搜索路径 PS1 命令提示符 PWD 用户的当前目录 SHELL 用户的shell类型 TERM 终端类型 HOME 用户主目录的位置,通常是/home/用户名
表中值得注意的是:PATH、PS1、SHELL、HOME几个变量在工作中使用率较高,需要关注。
我们也可以使用echo命令输出环境变量的值。
echo $PATH —$符表示提取变量的值,注:环境变量都为大写
另外,既然环境变量属于变量类型,那么它是可以人为更改的,下面我们就来看一下如何更改环境变量的值。
4.3.2 更改环境变量的值
我们可以直接使用=为环境变量设置新的值,称为赋值操作,如:
PS1=”{\u@\h \t \W}\$” —-更改命令提示符的显示格式,效果如下
命令中参数解释:\u用户名 \h主机名 \t时间 \d日期 \W当前相对路径
\w当前绝对路径 \$身份符
命令中未使用的参数,读者可自行尝试,查看效果。
注:\符的功能是提取后面字母的特殊含义,具体操作会在下一章中讲解。
\$是身份符的特定表示格式,因为$符在Linux中的含义较多,所以使用\$的格式。
在许多其他学习资料中会使用export变量=”值”的格式配置环境变量的值。其实用不用export关键字对环境变量赋值,会有使用范围(又称为生存期)上的区别,但对于初学者来说,效果基本差不多,所以在这里我们暂时不做过多的解释,大家可以理解为用不用export都可以实现赋值功能。有兴趣的读者也可以查阅相关资料加以区分。
4.4 环境变量配置文件
4.4.1 重启失效的原因
我们更改了环境变量,当注销或重启后会发现所做的设置失效了,这是为什么呢?其实Linux和Unix一样,对于系统运行状态的配置会有专门的文件进行记录,我们称之为配置文件,配置文件都记录在磁盘上,系统的每项设置都会有专用的配置文件做记录。
当开机时,Linux会从磁盘上读取配置文件到内存中,日常手动输入命令做的系统更改是生效给了内存中的配置信息,并未更改磁盘上的配置文件,而内存中的数据会在注销或重启后清空,所以在系统注销或重启后,配置失效。
因此,必须手动编辑、更改磁盘上的配置文件,才能永久生效。
4.4.2 配置环境变量配置文件
Linux关于环境变量的配置信息,有专用的环境变量配置文件,分为两类:系统环境变量配置文件和个人环境变量配置文件。
系统环境变量配置文件
针对整个Linux系统生效,所有账号登录后都会遵守
/etc/bashrc(针对shell) /etc/profile(针对外围程序)
个人环境变量配置文件
每个用户都有其独有的个人配置文件,仅针对单个用户生效,不影响其他用户
$HOME/.bashrc(针对shell)
$HOME/.bash_profile(针对外围程序)
$HOME/.profile(功能与.bash_profile相同,默认不存在)
我们可以根据需要,编辑配置文件,以完成重启生效的配置。实验如下
vi /etc/profile —在开头部分写入
PS1=”{\u@\h \t \W}\$”
注销或重启后查看效果
文件内容说明:该文件中开头部分会有很多#开头的文字。在Linux中,以#开头的都是注释内容。注释,即计算机在执行、查看文件时会掠过、不做处理的文字,一般是给使用者做些说明解释作用的文字。
另外,更改环境变量配置文件后,新的配置重启后,如果进入的是GUI图形界面,打开终端窗口后,会无效过;但重启后若进入字符界面,则效果明显,具体原因我们将在shell编程章节中做解释。
4.4.3 命令别名
Linux中还有一个较为常用的功能就是为命令设置别名。我们可以想象,如果有一个命令我们经常使用,但命令又比较复杂,每次输入比较麻烦,那么我们可以定义一个简洁的命令来替代该复杂的命令,称为命令别名。
如:cd /etc/sysconfig/network-scripts 该目录为Linux的网卡文件的存放位置,如果我们工作中会经常进入该目录做操作,那么我们就可以为该命令设置一个简洁的替代命令。命令如下:
alias wk=”cd /etc/sysconfig/network-scripts” —定义命令别名
则以后每次输入wk后,就等于输入了cd /etc/sysconfig/network-scripts。
alias —查看系统中的命令别名
unalias wk —取消命令别名
注:alias命令后可见到系统shell自带的和用户自定义的命令别名。
如:ll=”ls -l” 等
但是,与环境变量的特性相同,alias设置的命令别名,也只是临时生效的,注销或重启后即失效了,所以若想自定义的别名永久生效,也需要将设置命令写入到环境变量配置文件中。