zoukankan      html  css  js  c++  java
  • linux系统中的变量

    一、定义

    所谓的变量,就是就是利用一个特定的"名称"(name)来存取一段可以变化的"值"(value),简单说来就是“用一个名称储存一个数值”。

     

    二、设定(=)

    1. 如何设定变量

    在 bash 中,你可以用"=" 来设定或重新定义变量的内容:

    name=value

    2. 规则

    在设定变量的时侯,得遵守如下规则:

    • 等号左右两边不能使用字符分隔符(IFS),也应避免使用shell的其他元字符(meta charactor)。
    • 变量名称不能使用 $ 符号。
    • 变量名称的第一个字母不能是数字(number)。
    • 变量名称长度不可超过 256 个字母。
    • 变量名称及变量值之大小写是有区别的(case sensitive)。

    三、取消设定(unset)

    1. 取消变量

    要取消一个变量,在bash 中可使用 unset 命令来处理:

    unset 变量名

    变量一旦经过 unset 取消之后,其结果是将整个变量拿掉,而不仅是取消其变量值,如下两行其实是很不一样的:

    $ A=
    $ unset A

    第一行只是将变量 A 设定为"空值"(null value),但第二行则让变量 A 不在存在。虽然用echo命令输出都是一样的结果,但是在变量替换的时候却有着不同的效果。如:

    ${unknow=new}:若$unknow没有设定(unset),则使用new作为传回值,同时将unknow赋值为new,若unknow为空值或者非空值,则new对传回值与unknow均不影响,因此对于一个变量,它有只仅有三种状态:

    • 非空值(not null)
    • 空值(null)
    • 不设定(unset)

    四、变量替换

    1.普通替换

    在命令行中使用者可以使用 $ 符号加上变量名称(除了在用 = 号定义变量名称之外),

    将变量值给替换出来,然后再重新组建命令行。

    比方:

    A=ls
    B=la
    C=/tmp
    $A -$B $C

    在上面的最后一行命令中,在被执行之前(在输入 CR 字符之前),$符号会对每一个变量作替换处理(将变量值替换出来再重组命令行),最后会得出如下命令行:

    ls -la /tmp

    若从技术细节来看,shell会依据IFS将command line所输入的文字给拆解为"字段"(word)。然后再针对元字符(meta)先作处理,最后再重组整行command line。这里的 $ 就是 command line 中最经典的 meta 之一了,就是作变量替换的。

    2. 变量扩充

    我们也可利用命令行的变量替换能力来"扩充"(append)变量值:

    A=B:C:D
    A=$A:E

    这样,第一行我们设定 A 的值为 "B:C:D",然后,第二行再将值扩充为 "B:C:D:E" 。上面的扩充范例,我们使用区隔符号(:)来达到扩充目的,要是没有区隔符号的话,如下是有问题的:

    A=BCD
    A=$AE

    因为第二次是将 A 的值继承 $AE 的提换结果,而非 $A 再加 E ﹗要解决此问题,我们可用更严谨的替换处理:

    A=BCD
    A=${A}E

    上例中,我们使用 {} 将变量名称的范围给明确定义出来,如此一来,我们就可以将 A 的变量值从 BCD 给扩充为 BCDE 。

    3. ${}变量替换

    (1)一般情况下,$var 与 ${var} 并没有啥不一样。

    但是用${ }会比较精确的界定变量名称的范围,但更高级的用法是用来进行变量替换,假设我们定义了一个变量为:

    file=/dir1/dir2/dir3/my.file.txt

    我们可以用 ${ } 分别替换获得不同的值:

    ${file#*/}:拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
    ${file##*/}:拿掉最后一条 / 及其左边的字符串:my.file.txt
    ${file#*.}:拿掉第一个 .  及其左边的字符串:file.txt
    ${file##*.}:拿掉最后一个 .  及其左边的字符串:txt
    ${file%/*}:拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3
    ${file%%/*}:拿掉第一条 / 及其右边的字符串:(空值)
    ${file%.*}:拿掉最后一个 .  及其右边的字符串:/dir1/dir2/dir3/my.file
    ${file%%.*}:拿掉第一个 .  及其右边的字符串:/dir1/dir2/dir3/my

    记忆的方法为:

    [list]# 是去掉左边(在键盘上 # 在 $ 之左边)
    % 是去掉右边(在键盘上 % 在 $ 之右边)
    单一符号是最小匹配﹔两个符号是最大匹配。[/list]
    ${file:0:5}:提取最左边的 5 个字节:/dir1
    ${file:5:5}:提取第 5 个字节右边的连续 5 个字节:/dir2

    (2) 对变量值里的字符串作替换(接上面的例子):

    file=/dir1/dir2/dir3/my.file.txt
    ${file/dir/path}:将第一个 dir 替换为 path:/path1/dir2/dir3/my.file.txt
    ${file//dir/path}:将全部 dir 提换为 path:/path1/path2/path3/my.file.txt

    (3) 针对不同的变量状态赋值(没设定、空值、非空值)

    ${file-my.file.txt} :假如 $file 没有设定,则使用 my.file.txt 作传回值。(空值及非空值时不作处理)
    ${file:-my.file.txt} :假如 $file 没有设定或为空值,则使用 my.file.txt 作传回值。 (非空值时不作处理)
    ${file+my.file.txt} :假如 $file 设为空值或非空值,均使用 my.file.txt 作传回值。(没设定时不作处理)
    ${file:+my.file.txt} :若 $file 为非空值,则使用 my.file.txt 作传回值。 (没设定及空值时不作处理)
    ${file=my.file.txt} :若 $file 没设定,则使用 my.file.txt 作传回值,同时将 $file 赋值为my.file.txt 。 (空值及非空值时不作处理)
    ${file:=my.file.txt} :若 $file 没设定或为空值,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt 。(非空值时不作处理)
    ${file?my.file.txt} :若 $file 没设定,则将 my.file.txt 输出至 STDERR。 (空值及非空值时不作处理)
    ${file:?my.file.txt} :若 $file 没设定或为空值,则将 my.file.txt 输出至 STDERR。 (非空值时不作处理)

    以上的理解在于,你一定要分清楚unset与null及non-null这三种赋值状态。一般而言,:与null有关,若不带:的话,null不受影响,若带:则连null也受影响。还有哦,${#var}可计算出变量值的长度:

    ${#file} 可得到 27 ,因为/dir1/dir2/dir3/my.file.txt 刚好是 27 个字节...

    (4) 用来处理数组

    一般而言,A="a b c def" 这样的变量只是将 $A 替换为一个单一的字符串,但是改为 A=(a b c def) ,则是将 $A 定义为组数...

    bash 的组数替换方法可参考如下方法:

    ${A[@]} 或 ${A[*]} 可得到 a b c def (全部组数)
    ${A[0]} 可得到 a (第一个组数),${A[1]} 则为第二个组数...
    ${#A[@]} 或 ${#A[*]} 可得到 4 (全部组数数量)
    ${#A[0]} 可得到1 (即第一个组数(a)的长度),${#A[3]}可得到 3 (第四个组数(def)的长度) A[3]=xyz 则是将第四个组数重新定义为 xyz ...

    五、export

    严格来说,我们在当前shell中所定义的变量,均属于"本地变量"(local variable),只有经过 export 命令的"输出"处理,才能成为环境变量(environment variable):

    $ A=B
    $ export A
    或
    $ export A=B

    经过 export 输出处理之后,变量 A 就能成为一个环境变量供其后的命令使用。

    六、参考

    1. shell十三问

    (完)

    本文版权归作者(https://www.cnblogs.com/harrymore/)和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,如有问题, 可邮件(harrymore@126.com)咨询.
  • 相关阅读:
    2020_java面试
    Centos7.2 安装docker、mysql和redis
    【源码讲解】Spring事务是如何应用到你的业务场景中的?
    奇葩说今晚聊前任|扒一扒你的前任企业邮箱
    一封一封邮件发送太累?个人邮箱快速群发解决烦恼
    企业邮箱客户端收发服务器如何设置?
    163VIP邮箱怎么设置邮件签名?如何群发邮件?
    企业版邮箱哪个适合学校邮箱?企业邮箱托管服务
    企业版邮箱购买哪个?公司邮箱如何申请?
    公司邮箱登录入口是?公司邮箱申请入口在?
  • 原文地址:https://www.cnblogs.com/harrymore/p/5121444.html
Copyright © 2011-2022 走看看