Linux学习之十一、环境变量的功能

环境变量的功能

可以利用两个命令来查阅,分别是env与export呢!

范例一:列出目前的shell环境下的所有环境变量与其内容。

[root@www~]#env

SHELL

告知我们,目前这个环境使用的SHELL是哪支程序?Linux默认使用/bin/bash的啦!

HISTSIZE

这个与『历史命令』有关,亦即是,我们曾经下达过的命令可以被系统记录下来,而记录的『笔数』则是由这个值来配置的

LANG

这个重要!就是语系数据啰~很多信息都会用到他,举例来说,当我们在启动某些perl的程序语言文件时,

他会主动的去分析语系数据文件,如果发现有他无法解析的编码语系,可能会产生错误喔!一般来说,

我们中文编码通常是zh_TW.Big5或者是zh_TW.UTF-8,这两个编码偏偏不容易被解译出来,所以,有的时候,可能需要修订一下语系数据。

RANDOM

这个玩意儿就是『随机随机数』的变量啦!目前大多数的distributions都会有随机数生成器,那就是/dev/random这个文件。

[root@www~]#declare-inumber=$RANDOM*10/32768;echo$number

8<==此时会随机取出0~9之间的数值喔!

用set观察所有变量(含环境变量与自定义变量)

[root@www~]#set

一些较为重要的系统内定变量

PS1:(提示字符的配置)

这是PS1(数字的1不是英文字母),这个东西就是我们的『命令提示字符』喔!

当我们每次按下[Enter]按键去运行某个命令后,最后要再次出现提示字符时,就会主动去读取这个变量值了。

上头PS1内显示的是一些特殊符号,这些特殊符号可以显示不同的信息,每个distributions的bash默认的PS1变量内容可能有些许的差异,

不要紧,『习惯你自己的习惯』就好了。你可以用manbash(注3)去查询一下PS1的相关说明,以理解底下的一些符号意义。

\d:可显示出『星期月日』的日期格式,如:"MonFeb2"

\H:完整的主机名。举例来说,鸟哥的练习机为『www.vbird.tsai』

\h:仅取主机名在第一个小数点之前的名字,如鸟哥主机则为『www』后面省略

\t:显示时间,为24小时格式的『HH:MM:SS』

\T:显示时间,为12小时格式的『HH:MM:SS』

\A:显示时间,为24小时格式的『HH:MM』

\@:显示时间,为12小时格式的『am/pm』样式

\u:目前使用者的账号名称,如『root』;

\v:BASH的版本信息,如鸟哥的测试主板本为3.2.25(1),仅取『3.2』显示

\w:完整的工作目录名称,由根目录写起的目录名称。但家目录会以~取代;

\W:利用basename函数取得工作目录名称,所以仅会列出最后一个目录名。

\#:下达的第几个命令。

\$:提示字符,如果是root时,提示字符为#,否则就是$啰~

更改PS1变量的值:

[root@www~]#cd/home

[root@wwwhome]#PS1='[\u@\h\w\A#\#]\$’

[root@www/home17:02#85]#

#看到了吗?提示字符变了!变的很有趣吧!其中,那个#85比较有趣,

#如果您再随便输入几次ls后,该数字就会添加喔!为啥?上面有说明滴

$:(关于本shell的PID)

钱字号本身也是个变量喔!这个咚咚代表的是『目前这个Shell的线程代号』,亦即是所谓的PID(ProcessID)。

想要知道我们的shell的PID,就可以用:『echo$$』即可!出现的数字就是你的PID号码。

?:(关于上个运行命令的回传值)

什么?问号也是一个特殊的变量?没错!在bash里面这个变量可重要的很!这个变量是:『上一个运行的命令所回传的值』,

上面这句话的重点是『上一个命令』与『回传值』两个地方。当我们运行某些命令时,这些命令都会回传一个运行后的代码。

一般来说,如果成功的运行该命令,则会回传一个0值,如果运行过程发生错误,就会回传『错误代码』才对!一般就是以非为0的数值来取代。我们以底下的例子来看看:

[root@www~]#echo$SHELL

/bin/bash<==可顺利显示!没有错误!

[root@www~]#echo$?

0<==因为没问题,所以回传值为0

[root@www~]#12name=VBird

-bash:12name=VBird:commandnotfound<==发生错误了!bash回报有问题

[root@www~]#echo$?

127<==因为有问题,回传错误代码(非为0)

#错误代码回传值依据软件而有不同,我们可以利用这个代码来搜寻错误的原因喔!

[root@www~]#echo$?

0

#咦!怎么又变成正确了?这是因为"?"只与『上一个运行命令』有关,

#所以,我们上一个命令是运行『echo$?』,当然没有错误,所以是0没错!

OSTYPE,HOSTTYPE,MACHTYPE:(主机硬件与核心的等级)

目前个人计算机的CPU主要分为32/64位,其中32位又可分为i386,i586,i686,而64位则称为x86_64。

由于不同等级的CPU命令集不太相同,因此你的软件可能会针对某些CPU进行优化,以求取较佳的软件性能。

你可以在x86_64的硬件上安装i386的Linux操作系统,但是你无法在i686的硬件上安装x86_64的Linux操作系统

export:自定义变量转成环境变量

如你想要让该变量内容继续的在子程序中使用,那么就请运行:

[root@www~]#export变量名称

影响显示结果的语系变量(locale)

查看Linux支持的语言

[root@www~]#locale-a

….(前面省略)….

zh_TW

zh_TW.big5<==大五码的中文编码

zh_TW.euctw

zh_TW.utf8<==万国码的中文编码

如何修订这些编码呢?

[root@www~]#locale<==后面不加任何选项与参数即可!

LANG=en_US<==主语言的环境

LC_CTYPE="en_US"<==字符(文字)辨识的编码

LC_NUMERIC="en_US"<==数字系统的显示信息

LC_TIME="en_US"<==时间系统的显示数据

LC_COLLATE="en_US"<==字符串的比较与排序等

LC_MONETARY="en_US"<==币值格式的显示等

LC_MESSAGES="en_US"<==信息显示的内容,如菜单、错误信息等

LC_ALL=<==整体语系的环境

默认的语系定义在哪里

[root@www~]#cat/etc/sysconfig/i18n

LANG="zh_TW.UTF-8"

—————————-

变量的有效范围

被export后的变量,我们可以称他为『环境变量』!环境变量可以被子程序所引用,但是其他的自定义变量内容就不会存在于子程序中。

变量键盘读取、数组与宣告:read,array,declare

要读取来自键盘输入的变量,就是用read这个命令

[root@www~]#read[-pt]variable

选项与参数:

-p:后面可以接提示字符!

-t:后面可以接等待的『秒数!』这个比较有趣~不会一直等待使用者啦!

范例一:让用户由键盘输入一内容,将该内容变成名为atest的变量

[root@www~]#readatest

Thisisatest<==此时光标会等待你输入!请输入左侧文字看看

[root@www~]#echo$atest

Thisisatest<==你刚刚输入的数据已经变成一个变量内容!

范例二:提示使用者30秒内输入自己的大名,将该输入字符串作为名为named的变量内容

[root@www~]#read-p"Pleasekeyinyourname:"-t30named

Pleasekeyinyourname:VBirdTsai<==注意看,会有提示字符喔!

[root@www~]#echo$named

VBirdTsai<==输入的数据又变成一个变量的内容了!

————————-

declare/typeset

declare或typeset是一样的功能,就是在『宣告变量的类型』

[root@www~]#declare[-aixr]variable

选项与参数:

-a:将后面名为variable的变量定义成为数组(array)类型

-i:将后面名为variable的变量定义成为整数数字(integer)类型

-x:用法与export一样,就是将后面的variable变成环境变量;

-r:将变量配置成为readonly类型,该变量不可被更改内容,也不能unset

范例一:让变量sum进行100+300+50的加总结果

[root@www~]#sum=100+300+50

[root@www~]#echo$sum

100+300+50<==咦!怎么没有帮我计算加总?因为这是文字型态的变量属性啊!

[root@www~]#declare-isum=100+300+50

[root@www~]#echo$sum

[root@www~]#450

变量类型默认为『字符串』,所以若不指定变量类型

bash环境中的数值运算,默认最多仅能到达整数形态,所以1/3结果是0;

范例二:将sum变成环境变量

[root@www~]#declare-xsum

[root@www~]#export|grepsum

declare-ixsum="450"<==果然出现了!包括有i与x的宣告!

范例三:让sum变成只读属性,不可更动!

[root@www~]#declare-rsum

[root@www~]#sum=tesgting

-bash:sum:readonlyvariable<==老天爷~不能改这个变量了!

范例四:让sum变成非环境变量的自定义变量吧!

[root@www~]#declare+xsum<==将-变成+可以进行『取消』动作

[root@www~]#declare-psum<==-p可以单独列出变量的类型

declare-irsum="450"<==看吧!只剩下i,r的类型,不具有x啰

数组(array)变量类型

我有一个数组名为var,而这个数组的内容为var[1]=小明,var[2]=大明,var[3]=好明….

等等,那个index就是一些数字啦,重点是用中刮号([])来配置的

范例:配置上面提到的var[1]~var[3]的变量。

[root@www~]#var[1]="smallmin"

[root@www~]#var[2]="bigmin"

[root@www~]#var[3]="nicemin"

[root@www~]#echo"${var[1]},${var[2]},${var[3]}"

smallmin,bigmin,nicemin

———————————–

变量内容的删除、取代与替换

变量内容的删除与取代

变量的内容可以很简单的透过几个咚咚来进行删除喔!我们使用PATH这个变量的内容来做测试好了。

请你依序进行底下的几个例子来玩玩,比较容易感受的到鸟哥在这里想要表达的意义:

范例一:先让小写的path自定义变量配置的与PATH内容相同

[root@www~]#path=${PATH}

[root@www~]#echo$path

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:

/usr/sbin:/usr/bin:/root/bin<==这两行其实是同一行啦!

范例二:假设我不喜欢kerberos,所以要将前两个目录删除掉,如何显示?

[root@www~]#echo${path#/*kerberos/bin:}

/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

${variable#/*kerberos/bin:}

上面的特殊字体部分是关键词!用在这种删除模式所必须存在的

${variable#/*kerberos/bin:}

这就是原本的变量名称,以上面范例二来说,这里就填写path这个『变量名称』啦!

${variable#/*kerberos/bin:}

这是重点!代表『从变量内容的最前面开始向右删除』,且仅删除最短的那个

${variable#/*kerberos/bin:}

代表要被删除的部分,由于#代表由前面开始删除,所以这里便由开始的/写起。

需要注意的是,我们还可以透过通配符*来取代0到无穷多个任意字符

以上面范例二的结果来看,path这个变量被删除的内容如下所示:

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:

/usr/sbin:/usr/bin:/root/bin<==这两行其实是同一行啦!

范例三:我想要删除前面所有的目录,仅保留最后一个目录

[root@www~]#echo${path#/*:}

/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:

/root/bin<==这两行其实是同一行啦!

#由于一个#仅删除掉最短的那个,因此他删除的情况可以用底下的删除线来看:

#/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:

#/usr/sbin:/usr/bin:/root/bin<==这两行其实是同一行啦!

[root@www~]#echo${path##/*:}

/root/bin

#嘿!多加了一个#变成##之后,他变成『删除掉最长的那个数据』!亦即是:

#/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:

#/usr/sbin:/usr/bin:/root/bin<==这两行其实是同一行啦!

非常有趣!不是吗?因为在PATH这个变量的内容中,每个目录都是以冒号『:』隔开的,所以要从头删除掉目录就是介于斜线(/)到冒号(:)之间的数据!

但是PATH中不止一个冒号(:)啊!所以#与##就分别代表:

#:符合取代文字的『最短的』那一个;

##:符合取代文字的『最长的』那一个

范例四:我想要删除最后面那个目录,亦即从:到bin为止的字符串

[root@www~]#echo${path%:*bin}

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:

/usr/sbin:/usr/bin<==注意啊!最后面一个目录不见去!

#这个%符号代表由最后面开始向前删除!所以上面得到的结果其实是来自如下:

#/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:

#/usr/sbin:/usr/bin:/root/bin<==这两行其实是同一行啦!

范例五:那如果我只想要保留第一个目录呢?

[root@www~]#echo${path%%:*bin}

/usr/kerberos/sbin

#同样的,%%代表的则是最长的符合字符串,所以结果其实是来自如下:

#/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:

#/usr/sbin:/usr/bin:/root/bin<==这两行其实是同一行啦!

由于我是想要由变量内容的后面向前面删除,而我这个变量内容最后面的结尾是『/root/bin』,所以你可以看到上面我删除的数据最终一定是『bin』,亦即是『:*bin』那个*代表通配符!

至于%与%%的意义其实与#及##类似!这样理解否?

例题:

假设你是root,那你的MAIL变量应该是/var/spool/mail/root。假设你只想要保留最后面那个档名(root),前面的目录名称都不要了,如何利用$MAIL变量来达成?

答:

题意其实是这样『/var/spool/mail/root』,亦即删除掉两条斜线间的所有数据(最长符合)。这个时候你就可以这样做即可:

[root@www~]#echo${MAIL##/*/}

相反的,如果你只想要拿掉文件名,保留目录的名称,亦即是『/var/spool/mail/root』(最短符合)。但假设你并不知道结尾的字母为何,此时你可以利用通配符来处理即可,如下所示:

[root@www~]#echo${MAIL%/*}

了解了删除功能后,接下来谈谈取代吧!继续玩玩范例六啰!

范例六:将path的变量内容内的sbin取代成大写SBIN:

[root@www~]#echo${path/sbin/SBIN}

/usr/kerberos/SBIN:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:

/usr/sbin:/usr/bin:/root/bin

#这个部分就容易理解的多了!关键词在于那两个斜线,两斜线中间的是旧字符串

#后面的是新字符串,所以结果就会出现如上述的特殊字体部分啰!

[root@www~]#echo${path//sbin/SBIN}

/usr/kerberos/SBIN:/usr/kerberos/bin:/usr/local/SBIN:/usr/local/bin:/SBIN:/bin:

/usr/SBIN:/usr/bin:/root/bin

#如果是两条斜线,那么就变成所有符合的内容都会被取代喔!

总结:

变量配置方式 说明

${变量#关键词}若变量内容从头开始的数据符合『关键词』,则将符合的最短数据删除

${变量##关键词} 若变量内容从头开始的数据符合『关键词』,则将符合的最长数据删除

${变量%关键词}若变量内容从尾向前的数据符合『关键词』,则将符合的最短数据删除

${变量%%关键词} 若变量内容从尾向前的数据符合『关键词』,则将符合的最长数据删除

${变量/旧字符串/新字符串}若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串取代』

${变量//旧字符串/新字符串}若变量内容符合『旧字符串』则『全部的旧字符串会被新字符串取代』

—————————

变量的测试与内容替换

在某些时刻我们常常需要『判断』某个变量是否存在,若变量存在则使用既有的配置,若变量不存在则给予一个常用的配置。

我们举底下的例子来说明好了,看看能不能较容易被你所理解呢!

范例一:测试一下是否存在username这个变量,若不存在则给予username内容为root

[root@www~]#echo$username

<==由于出现空白,所以username可能不存在,也可能是空字符串

[root@www~]#username=${username-root}

[root@www~]#echo$username

root<==因为username没有配置,所以主动给予名为root的内容。

[root@www~]#username="vbirdtsai"<==主动配置username的内容

[root@www~]#username=${username-root}

[root@www~]#echo$username

vbirdtsai<==因为username已经配置了,所以使用旧有的配置而不以root取代

new_var=${old_var-content}

新的变量,主要用来取代旧变量。新旧变量名称其实常常是一样的

new_var=${old_var-content}

这是本范例中的关键词部分!必须要存在的哩!

new_var=${old_var-content}

旧的变量,被测试的项目!

new_var=${old_var-content}

变量的『内容』,在本范例中,这个部分是在『给予未配置变量的内容』

不过这还是有点问题!因为username可能已经被配置为『空字符串』了!果真如此的话,那你还可以使用底下的范例来给予username的内容成为root喔!

范例二:若username未配置或为空字符串,则将username内容配置为root

[root@www~]#username=""

[root@www~]#username=${username-root}

[root@www~]#echo$username

<==因为username被配置为空字符串了!所以当然还是保留为空字符串!

[root@www~]#username=${username:-root}

[root@www~]#echo$username

root<==加上『:』后若变量内容为空或者是未配置,都能够以后面的内容替换!

测试:先假设str不存在(用unset),然后测试一下减号(-)的用法:

[root@www~]#unsetstr;var=${str-newvar}

[root@www~]#echovar="$var",str="$str"

var=newvar,str=<==因为str不存在,所以var为newvar

测试:若str已存在,测试一下var会变怎样?:

[root@www~]#str="oldvar";var=${str-newvar}

[root@www~]#echovar="$var",str="$str"

var=oldvar,str=oldvar<==因为str存在,所以var等于str的内容

测试:先假设str不存在(用unset),然后测试一下等号(=)的用法:

[root@www~]#unsetstr;var=${str=newvar}

[root@www~]#echovar="$var",str="$str"

var=newvar,str=newvar<==因为str不存在,所以var/str均为newvar

测试:如果str已存在了,测试一下var会变怎样?

[root@www~]#str="oldvar";var=${str=newvar}

[root@www~]#echovar="$var",str="$str"

var=oldvar,str=oldvar<==因为str存在,所以var等于str的内容

测试:若str不存在时,则var的测试结果直接显示"无此变量"

[root@www~]#unsetstr;var=${str?无此变量}

-bash:str:无此变量<==因为str不存在,所以输出错误信息

测试:若str存在时,则var的内容会与str相同!

[root@www~]#str="oldvar";var=${str?novar}

[root@www~]#echovar="$var",str="$str"

var=oldvar,str=oldvar<==因为str存在,所以var等于str的内容

『 不可能 』只存在於蠢人的字典里

Linux学习之十一、环境变量的功能

相关文章:

你感兴趣的文章:

标签云: