zoukankan      html  css  js  c++  java
  • 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 -i number=$RANDOM*10/32768 ; echo $number

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

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

    [root@www ~]# set

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

    PS1(提示字符的配置)

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

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

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

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

    :可显示出『星期 月 日』的日期格式,如:"Mon Feb 2"

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

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

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

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

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

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

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

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

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

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

    :下达的第几个命令。

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

    更改PS1变量的值:

    [root@www ~ ]# cd /home

    [root@www home]# PS1='[u@h w A ##]$ '

    [root@www /home 17:02 #85]# 

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

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

    $(关于本 shell 的 PID)

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

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

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

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

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

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

    [root@www ~]# echo $SHELL

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

    [root@www ~]# echo $?

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

    [root@www ~]# 12name=VBird

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

    [root@www ~]# echo $?

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

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

    [root@www ~]# echo $?

    0

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

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

    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 ~]# read atest

    This is a test        <==此时光标会等待你输入!请输入左侧文字看看

    [root@www ~]# echo $atest

    This is a test          <==你刚刚输入的数据已经变成一个变量内容!

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

    [root@www ~]# read -p "Please keyin your name: " -t 30 named

    Please keyin your name: VBird Tsai   <==注意看,会有提示字符喔!

    [root@www ~]# echo $named

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

    -------------------------

    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 -i sum=100+300+50

    [root@www ~]# echo $sum

    [root@www ~]# 450

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

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

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

    [root@www ~]# declare -x sum

    [root@www ~]# export | grep sum

    declare -ix sum="450"  <==果然出现了!包括有 与 的宣告!

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

    [root@www ~]# declare -r sum

    [root@www ~]# sum=tesgting

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

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

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

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

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

    数组 (array) 变量类型

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

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

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

    [root@www ~]# var[1]="small min"

    [root@www ~]# var[2]="big min"

    [root@www ~]# var[3]="nice min"

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

    small min, big min, nice min

    -----------------------------------

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

    变量内容的删除与取代

    变量的内容可以很简单的透过几个咚咚来进行删除喔!我们使用 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:}

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

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

       以上面范例二的结果来看, 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="vbird tsai" <==主动配置 username 的内容

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

    [root@www ~]# echo $username

    vbird tsai <==因为 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 ~]# unset str; var=${str-newvar}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 相关阅读:
    iPhone开发应用Sqlite使用手册
    2.23 Apps must follow the iOS Data Storage Guidelines or they will be rejected
    跨浏览器(IE/FF/OPERA)JS代码小结
    c#一次数据库查询,JS实现内容分页
    oracle PLSQL /sqlserver2005基本操作对比
    SqlParameter构造函数的临界边缘
    SQL SERVER 2005分页存储过程
    *自创*可变长度随机数字/字母的生成小结(针对文件上传及验证码)
    Visual Source Safe连接数据文件图解 解决密码缓存问题
    [Ubuntu] Invalid command 'VirtualDocumentRoot', perhaps misspelled or defined by a module not included in the server configuration
  • 原文地址:https://www.cnblogs.com/raphael5200/p/5114829.html
Copyright © 2011-2022 走看看