Linux学习笔记(四)

随笔2018-06-1413 分钟linuxshell

接下来一段时间打算学一下linux 学习来源书本《Linux命令行与shell脚本编程大全 第三版》

一、SHELL环境变量

bash shell用一个叫做环境变量(environment variable)的特性来存储有关shell会话和工作环境的信息。(这也是它们被称作环境变量的原因)。这项特性允许你在内存中存储数据,以便程序或shell中运行的脚本能够轻松访问到它们。这也是存储持久数据的一种简便方法。

在bash shell中,环境变量分为两类:

全局变量:对于shell会话和所有生成的子shell都是可见的。可用来进行父子shell程序通信。
局部变量:只对创建它们的shell可见。

全局环境变量

env # 打印出所有的全局变量
printenv # 同上
printenv {变量名} # 打印出特定环境变量
echo ${变量名} # 同上

ps:在echo命令中,在变量名前加 $ 不仅能够显示变量当前的值,还能让变量作为命令行参数。

eg:

echo $HOME # 打印出HOME的值
ls $HOME # ls HOME值目录下的文件列表

局部环境变量

Linux系统默认定义了标准的局部环境变量。 除此之外,用户也可以定义自己的局部变量,这些变量被称为 用户定义局部变量

和全局变量不一样,Linux系统没有一个只显示局部环境变量的命令。

set # 会显示某个特定进程设置的所有环境变量(包括全局、局部、用户定义局部变量)
somekey=somevalue # 定义用户局部变量。注意:等号两边不能有空格、不能再子shell中引用

用户自定义全局环境变量

很显然系统自带的全局环境变量、自带的局部环境变量以及用户定义局部变量并不能满足父子shell进程之间的通讯 因此,linux还允许用户设置自定义全局变量。

somekey=somevalue # 先创建一个局部环境变量
export somekey # 再通过export将其导入到全局变量变量。注意:不需要$符号。

export somekey=somevalue # 一键创建全局环境变量

特别注意: 1.在父进程中修改的全局变量会影响子进程中的该变量; 2.但是在子进程中修改该变量不会影响到父进程中的该变量。即使再通过export导出也不会影响父进程,只会影响当前子进程的子进程。

删除环境变量

unset somekey # 删除环境变量。注意:不需要$符号

注意:同创建环境变量一样,子进程中删除在父进程中export导出的全局环境变量不会影响到父进程。

设置PATH环境变量

当在shell命令行界面中输入一个外部命令时,shell必须搜索系统来找到对应的程序。 PATH环境变量定义了用于进行命令和程序查找的目录。

eg:

$ echo $PATH # 输出系统环境变量
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Wireshark.app/Contents/MacOS:/usr/local/mysql/bin

执行某个命令的时候,系统会依次从上面输出的6个目录中,查找可执行命令的程序。如果找不到就会报错。

用户添加自己的命令到系统环境变量中只需要使用如下命令,将可执行文件目录添加到原有的系统环境变量PATH后面。

PATH=$PATH:/home/xxx/scripts/bin

可持续使用的自定义系统环境变量

自定义变量的方法可以按照前面说的定义用户局部系统变量、或者用export导出为全局系统变量。 但是,这种方式创建的变量是临时的,当前shell进程结束之后就会失效。

要想永久的保存自定义变量,可以根据shell的启动过程,修改其启动时需要读取命令的文件。 如下面几个文件。

/etc/profile # 系统默认的bash shell主启动文件,系统上每个用户登录都会执行此文件
~/.bash_profile
~/.bashrc
~/.bash_login
~/.profile

shell会按照下列顺序,运行第一个被找到的问题件,找到之后则忽略后面的

~/.bash_profile
~/.bash_login
~/.profile

注意:这个列表中没有~/.bashrc文件,这是因为该文件往往是在其它文件(如:.profile,也可能是.bash_profile)中被执行的。

交互式shell进程

如果你的bash shell不是登录系统时启动的,那么你启动的shell叫做交互式shell。 交互式shell不会像登录shell一样运行,但它依然提供了命令行提示符来输入命令。 通俗来说,就是在终端,shell等待用户输入,然后执行用户输入的命令。

非交互式shell

系统执行shell脚本时用的就是非交互式shell。不同于交互式shell的地方在于它没有命令行提示符。 这种模式下,shell不会与用户进行交互,执行完shell script脚本 shell也就终止了。

交互式shell和非交互式shell的区别在于: 如果bash是作为交互式shell启动的,它就不会访问/etc/profile文件,只会检查用户HOME目录中的.bashrc文件。 非交互式shell,当启动进程时,它会检查这个BASH_SHELL环境变量,读取的是环境变量所指定的配置文件。 (BASH_SHELL这个环境变量默认情况下并未设置)

login bash

登录shell可以让用户与计算机交流

no login bash

非登录shell不可用让用户与计算机交流。 比如用linux服务器搭建一个ftl服务器,并且创建了很多用户,那么可以将这些用户设置为nologin shell。 这样,这些用户仅仅可以使用ftl服务,不能用来登录Linux主机,保证了安全性。

关于用户的默认登录shell是在 /etc/passwd 文件中记录的。此文件中每一行就是一个用户,每行以冒号分割字段,其中最后一个字段表示的是用户默认登录使用的shell。

环境变量持久保存两个方法

1.将个人环境变量设置放在/etc/profile.d目录中,创建一个.sh结尾的文件,将所有新的或者修改过的全局环境变量设置放在这个文件中。 2.放在~/.bashrc文件中。

数组变量

环境变量可作为数组使用。 数组是能够存储多个值的变量。 这些值可以单独引用,也可以作为整个数组来引用。

$ somekey=(one two three four five)
$ echo $somekey
one two three four five
$ echo ${somekey[2]}
three # 这里有问题,mac上输出的是‘two’ !!!,linux虚拟机上输出是‘three’!!!
$ echo ${somekey[*]} # 输出全部,mac上可以不用{},用此属性需谨慎。

附录 - 默认环境变量

bash shell 支持的Bourne变量

变量描述
CDPATH冒号分隔的目录列表,作为cd命令的搜索
HOME当前用户的主目录
IFSsell用来将文本字符串分割成字段的一系列字符
MAIL当前用户收件箱的文件名(bash shell会检查这个文件,看看有没有新的邮件)
MAILPATH冒号分隔的当前用户收件箱的文件名列表(bash shell会检查列表中的每个文件,看看有没有新邮件)
OPTARGgetopts命令处理的最后一个选项参数值
OPTINDgetopts命令处理的最后一个选项参数的索引号
PATHshell查找命令的目录列表,由冒号分隔
PS1shell命令行界面的主提示符
PS2sell命令行界面的次提示符
bash shell环境变量

除了默认的Bourme的环境变量,bash shell还提供一此 自有的变量

变量描述
BASH当前shel实例的全路径名
BASH_ALIASES含有当前已设置别名的关联数组
BASH_ARGC含有传入子函数或shel脚本的参数总数的数组变量
BASH_ARCV含有传入子函数或shell脚本的参数的数组变量
BASH_CMDS关联数组,包含shell执行过的命令的所在位置
BASH_COMMANDshell正在执行的命令或马上就执行的命令
BASH_ENV设置了的话,每个bash脚本会在运行前先尝试运行该变量定义的启动文件
BASH_EXECUTION_STRING使用bash -c选项传递过来的命令
BASH_LINENO含有当前执行的shell函数的源代码行号的数组变量
BASH_REMATCH只读数组,在使用正则表达式的比较运算符=~进行肯定匹配(positive match)时, 包含了匹配到的模式和子模式
BASH_SOURCE含有当前正在执行的hel函数所在源文件名的数组变量
BASH_SUBSHELL当前子shell环境的嵌套级别(初始值是0)
BASH_VERSINFO含有当前运行的bash shell的主版本号和次版本号的数组变量
BASH_VERSION当前运行的bash shell的版本号
BASH_XTRACEFD若设置成了有效的文件描述符(0,1,2)则'set -x' 调试选项生成的跟踪输出可被重定向。通常用来将跟踪输出到一个文件中
BASHOPTS当前启用的bash shell选项的列表
BASHPID当前bash进程的PID
COLUMNS当前bash shell实例所用终端的宽度
COMP_CWORDCOMP_WORDS变量的索引值,后者含有当前光标的位置
COMP_LINE当前命令行
COMP_POINT当前光标位置相对于当前命令起始的索引
COMP_KEY用来调用shell函数补全功能的最后一个键
COMP_TYPE一个整数值,表示所尝试的补全类型,用以完成shell函数补全
COMP_WORDBREAKSReadline库中用于单词补全的词分隔字符
COMP_WORDS含有当前命令行所有单词的数组变量
COMPREPLY含有由shell函数生成的可能填充代码的数组变量
COPROC占用未命名的协进程的I/O文件描述符的数组变量
DIRSTACK含有目录栈当前内容的数组变量
EMACS设置为't' 时,表明emacs shell缓冲区正在工作,而行编辑功能被禁止
ENV如果设置了该环境变量,在bash shell脚本运行之前会先执行已定义的启动文件(仅用于当bash shell以IPOSIX模式被调用时)
EUID当前用户的有效用户ID (数字形式)
FCEDIT供fc命令使用的默认编辑器
FIGNORE在进行文件名补全时可以忽略后缀名列表,由冒号分隔
FUNCNAME当前执行的shell函数的名称

变量描述
FUNCNEST当设置成非零值时,表示所允许的最大函数嵌套级数(一旦超出,当前命令即被终止)
GLOBIGNORE冒号分隔的模式列表,定义了在进行文件名扩展时可以忽略的一组文件名
GROUPS含有当前用户属组列表的数组变量
histchars控制历史记录扩展,最多可有3个字符
HISTCMD当前命令在历史记录中的编号
HISICONTROL控制哪些命令留在历史记录列表中
HISTFILE保存shell历史记录列表的文件名(默认是bash history)
hISTFILESIZe最多在历史文件中存多少行
HISTTIMEFORMAT如果设置了且非空,就用作格式化字符串,以显示bash历史中每条命令的时间戳
HISTIGNORE由冒号分隔的模式列表,用来决定历史文件中哪些命令会被忽略
HISTSIZE最多在历史文件中存多少条命令
HOSTFILEshell在补全主机名时读取的文件名称
HOSTNAME当前主机的名称
HOSTTYPE当前运行bash shell的机器
IGNOREEOFsell在退出前必须收到连续的BOF字符的数量(如果这个值不存在,默认是1)
INPUTRCReadline 初始化文件名(默认是.inputrc)
LANGshell的语言环境类别
LC_ALL定义了一个语言环境类别,能够覆盖LANG变量
LC_COLLATE设置对字符串排序时用的排序规则
LC_CTYPE决定如何解释出现在文件名扩展和模式匹配中的字符
LC_MESSAGES在解释前面带有S的双引号字符串时,该环境变量决定了所采用的语言环境设置
LC_NUMERIC决定着格式化数字时采用的语言环境设置
LINENO当前执行的脚本的行号
LINES定义了终端上可见的行数
MACHTYPE用“CPU-公司-系统”(CPU-company-system) 格式定义的系统类利
MAPFILE一个数组变量, 当mapfile命令未指定数组变量作为参数时,它存储了 mapfile 所读入的文本
MAILCHECKshell查看新邮件的频率(以秒为单位,默认值是60)
OLDPWDshell之前的工作目录
OPTERR设置为1时,bash sell会显示getopts命令产生的错误
OSTYPE定义shell所在的操作系统
PIPESTATUS含有前台进程的退出状态列表的数组变量
POSIXLY_CORRECT设置了的话,bas会以POSsx模式启动
PPIDbash sell父进程的PID
PROMPT_COMMAND设置了的话,在命令行主提示符显示之前会执行这条命令
PROMPT_DIRTRIM用来定义当启用了\w或\W提示符字符串转义时显示的尾部目录名的数量。被删除的目录名会用一组英文句点替换
PS3select命令的提示符
PS4如果使用了bash的一x选项,在命令行之前显示的提示信息
PWD当前工作目录
RANDOM返回一个0~ 32767的随机数(对其的赋值可作为随机数生成器的种子)
READLINE_LINE当使用bind -x命令时,存储Readline缓冲区的内容
READLINE_POINT当使用bind -x命 令时,表示Readine缓冲区内容插人点的当前位置
REPLYread命令的默认变量
SECONDS自从shell启动到现在的秒数(对其赋值将会重置计数器)
SHELLbash shell的全路径名
SHELLOPTS已启用bash shell选项列表,列表项之间以冒号分隔
SHLVLshell的层级;每次启动一个新bash shell,该值增加1
TIMEFORMAT指定了shell的时间显示格式
TMOUTselect和read命令在没输人的情况下等待多久(以秒为单位)。默认值为0,表示无限长
TMPDIR目录名,保存bash shell创建的临时文件
UID当前用户的真实用户ID (数字形式)