• Shell脚本中常见的几种变量类型


    环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。
    简单来说,环境变量是系统的变量,当要用到某个程序的时候,告诉系统根据环境变量中设置的路径(path)去哪个地方找这个程序

    变量

    export 可以查看(显示)Shell 环境变量。

    1)局部变量:固定用户,固定shell环境中可以调用的变量,当用户切换shell环境或切换用户时,该变量失效。
    用户默认创建的变量都是局部变量(也就是自定义变量)

    2)全局变量:固定用户,但更新shell环境后还能使用的变量,切换用户后变量失效。
    可以将局部变量转换为全局变量,也可以直接定义全局变量(环境变量)
    格式1:export 变量名 …
    格式2:export 变量名=变量值 …

    3)使用sh调用脚本时,会清除内存中的变量
    使用. 脚本名加载脚本时,会在内存中保留变量

    在 Linux 系统中,除了 export 之外,env、set 和 declare 这三个命令也可以显示 Shell 中的变量。那这四个命令有什么区别呢?
    这个问题,我们需要从 Shell 变量说起。Shell的变量,可以分为“环境变量”和“自定义变量”两种类型,两者的区别在于作用范围不同。环境变量可以在其进程的子进程中继续有效,而自定义变量的势力范围则无法延伸到其进程的子进程中。

    好了,知道了环境变量和自定义变量的区别,我们正式开始介绍 export/env/set/declare 的区别:

    env			显示当前用户的环境变量,但不会显示其自定义变量。
    export	    功能同env一样,也是显示当前用户的环境变量,只不过该命令的输出是按变量名进行排序的。
    declare     显示当前 Shell 中定义的所有变量,包括用户的环境变量和自定义变量,该命令的输出按变量名进行排序。
    set         功能同declare一样,显示当前 Shell 中定义的所有变量,包括用户的环境变量和自定义变量。
    
    • 1
    • 2
    • 3
    • 4

    【根据上面的说明,我们可以得出下面的结论: env 和 export 显示的是环境变量 set 和 declare 显示的是环境变量和自定义变量】

    我们以 set 和 declare 为例,来看一下是否真的是这样:

    [root@localhost ~]# set > set.txt
    [root@localhost ~]# declare > declare.txt
    [root@localhost ~]# diff set.txt declare.txt
    < _=clear
    ---
    > _=set
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    可以看到,set 和 declare 的输出几乎是一样的。唯一的区别就在于这个“下划线变量”。下划线变量(_)表示用户上一次输入的命令的最后一个参数。上面两条命令之所以出现不同,是因为在执行 set 前执行了 clear 命令,而在执行 declare 之前,执行了 set 命令。

    设置 Shell 环境变量

    $PATH 环境变量是 Linux 系统中最常用的变量之一,我们先来看一下这个变量的内容:

    [root@localhost ~]# echo $PATH		$PATH 变量的值是由多个路径所组成的,并且用冒号进行了分隔。
    /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin
    
    • 1
    • 2

    这些路径的作用是什么呢?
    当用户在 Linux 系统中直接输入一个命令(如 date 命令),而没有指定其绝对路径时,Linux 就会求助于 $PATH 啦!Linux 会依次进入到 $PATH 变量所指定的各个路径中,去寻找是否存在此命令(date 命令),如果找到了就执行该命令;如果没有找到就直接退出,并提示用户未找到该命令。

    在运维工作中,用好 $PATH 变量是可以大大提升工作效率的。假如 /home/roc/operation_tools 文件夹下存放着我们自制的各种运维小工具,每次使用这些小工具时又不想总指定其绝对路径,那么,我们应该怎么办呢?没错,我们应该把这个路径追加到 $PATH 变量中去,具体的做法是这样:

    export PATH=$PATH:/home/roc/operation_tools
    
    • 1

    上述命令执行成功后,我们的运维小工具就可以直接被 Linux 系统找到了。从此以后,当我们想使用这些运维小工具时,就再也不用指定绝对路径啦。

    export的作用:
    使用 export 设置的变量就成为了环境变量,而没有使用 export 设置的则是自定义变量。 环境变量可以在其进程的子进程中继续有效,而自定义变量则无效。

    模拟误操作:

    # 命令中缺少了 $PATH,这样会清空原来 $PATH 的内容。$PATH 中没有了系统指定的路径 Linux 就无法找到要执行的命令
    export PATH=/home/to/operation_tools 
    
    • 1
    • 2

    变量类型

    局部变量

    只对当前的shell生效

    [root@lala ~]# a=5
    [root@lala ~]# echo $a
    5
    [root@lala ~]# bash
    [root@haha ~]# echo $a
    
    [root@haha ~]# exit
    exit
    [root@lala ~]# echo $a
    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    全局变量

    对所有shell都生效

    # 方法1:
    [root@lala ~]# export a=4
    [root@lala ~]# bash
    [root@haha ~]# echo $a
    4
    
    # 方法2:
    [root@lala ~]# a=1.6
    [root@lala ~]# export
    [root@lala ~]# bash
    [root@haha ~]# echo $a
    1.6
    
    [root@lala ~]# echo $PATH
    /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin
    [root@lala ~]# export PATH=$PATH:/usr/local/httpd/bin
    [root@lala ~]# echo $PATH
    /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/httpd/bin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    用户变量

    只对某个用户生效,配置文件宿主目录下.bash_profile和.bashrc

    例:现在公司有一个《guizhangzhidu》,要求所有新员工账户中都有此文件。

    [root@lala zs]# cd /etc/skel/
    [root@lala skel]# ls -a
    .  ..  .bash_logout  .bash_profile  .bashrc  .mozilla
    [root@lala skel]# touch gongsiguizhangzhidu.txt
    [root@lala skel]# ls -a
    .  ..  .bash_logout  .bash_profile  .bashrc  gongsiguizhangzhidu.txt  .mozilla
    [root@lala skel]# useradd ls
    [root@lala skel]# cd /home/ls
    [root@lala ls]# ls -a
    .  ..  .bash_logout  .bash_profile  .bashrc  gongsiguizhangzhidu.txt  .mozilla
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    =================

    系统变量

    对所有用户都生效,配置文件/etc/profile和/etc/bashrc

    [root@lala ls]# vim /etc/profile
    写在最后一行:
    export PATH=$PATH:/usr/local/httpd/conf
    [root@lala ls]# source /etc/profile
    [root@lala ls]# echo $PATH
    /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/usr/local/httpd/bin:/usr/local/httpd/bin:/usr/local/httpd/bin:/usr/local/httpd/conf/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    自定义变量

    用户自己定义的变量

    声明变量:[varname]=[varvalues] 【值为空的话,会影响“字符串比较”这一操作】
    查看变量:echo $varname

    # 例:
    [root@lala ls]# vim /mount.sh
    #!/bin/bash
    #install mount		注释
    a=/dev/cdrom
    b=/media/dvd
    
    #mount media		注释
    mount $a $b
    
    [root@lala ls]# bash /mount.sh
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    位置变量

    表示为 $n,n为1~9之间的数字
    格式:
    [root@localhost ~]# ./myprog.sh one two three four five six {one代表第一个位置参数,two代表第二个位置参数,…}

    [root@lala ~]# a=5
    [root@lala ~]# echo $a
    5
    [root@lala ls]# n=(1 2 3 4)
    [root@lala ls]# echo ${n[0]}
    1
    [root@lala ls]# echo ${n[1]}
    2
    [root@lala ls]# echo ${n[2]}
    3
    [root@lala ls]# echo ${n[3]}
    4
    例:
    vim 2.sh
    添加:
    SUM=`expr  $1  +  $2`
    echo  "$1  +  $2  =  $SUM"
    [root@localhost ~]# chmod +x 2.sh
    [root@localhost ~]# ./2.sh 2 4
    2  +  4  =  6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    预定义变量

    bash中内置的一类变量,不能直接修改

    $#:位置变量个数
    $*:位置变量内容
    $?:返回上一条命令执行结果状态码,0执行正确 1-255执行错误            例:echo $?
    $0:命令字{当前执行的进程/程序名}
    $@  是传给脚本的所有参数的列表			//$@$*都表示命令行所有参数(不包含$0),但是$*将命令行的所有参数看成一个整体,而$@则区分各个参数
     #/dev/null称为黑洞设备,放在这里的信息都不再显示。
     
    第一种方法:(错误写法)
    Vim 1.sh
    a=1
    b=2
    SUM=`expr $a + $b`
    echo "$a + $b =$SUM"
    qwer=huaizhe.`date +%s`.tar.gz
    tar zcvf $qwer $* /tmp &>1.txt
    echo "已执行 $0 脚本,"
    echo "共完成 $# 个对象的备份"
    echo   "具体内容包括: $*" 
    效果图:
    [root@localhost ~]# sh 1.sh 
    1 + 2 =3
    已执行 1.sh 脚本,
    共完成 0 个对象的备份
    具体内容包括:                             //虽然当前目录下有备份文件,但是“共完成0个对象的备份”~
    ---------------------
    第二种:(正确写法)
    [root@localhost ~]# chmod a+x 1.sh
    添加:
    SUM=`expr $1 + $2`
    echo "$1 + $2 =$SUM"
    qwer=huaizhe.`date +%s`.tar.gz
    tar zcvf $qwer $* /tmp &>1.txt
    echo "已执行 $0 脚本,"
    echo "共完成 $# 个对象的备份"
    echo   "具体内容包括: $*“
    效果图:
    [root@localhost ~]# ./1.sh 1 2
    1 + 2 =3
    已执行 ./1.sh 脚本,
    共完成 2 个对象的备份
    具体内容包括: 1 2                      //ls可以查看到备份的文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    变量赋值的特殊操作(引号)

    " ":可以显示变量

    [root@lala ls]# t318=bufang tongxie
    bash: tongxie: 未找到命令...
    [root@lala ls]# t318="bufang tongxie"
    [root@lala ls]# echo $t318
    bufang tongxie
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ' '(英文单引号):强引用,引用普通字符

    [root@lala ls]# t217='yang $t318'
    [root@lala ls]# echo $t217
    yang $t318
    
    • 1
    • 2
    • 3
    `  `(数字键盘1,esc下面):反撇号,引用命令执行结果
    # 例:
    [root@lala ls]# ls -lh /usr/bin/tar
    -rwxr-xr-x. 1 root root 338K 116 2016 /usr/bin/tar
    [root@lala ls]# ls -lh $(which tar)
    -rwxr-xr-x. 1 root root 338K 116 2016 /usr/bin/tar
    [root@lala ls]# aa=$(ls -lh $(which tar))
    [root@lala ls]# echo $aa
    -rwxr-xr-x. 1 root root 338K 116 2016 /usr/bin/tar
    同等于
    [root@lala ls]# ls -lh `which tar`
    cat /etc/httpd/conf/httpd.conf | grep -v "^#" | grep -v "^;" | grep -v "^$"
    htlist=` cat /etc/httpd/conf/httpd.conf | grep -v "^#" | grep -v "^;" | grep -v "^$"
    `
    echo $htlist
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    read:交互中,提示用户输入信息

    \ :转移符,把一些特殊的字符转化成本身代表的字符,正则表达式中多用

    整数变量的运算
    含义:
    shell脚本的数值运算多用于脚本程序的过程控制(如循环次数,使用量比较等)
    在shell环境中,只能进行比较简单的整数运算!!!
    运算符与变量之间必须有一个空格位,整数的运算主要是通过内部命令expr 命令进行运算 expr:简单计算器;表达式
    格式 变量1 运算符 变量2

     加法运算:+
     减法运算: -
     乘法运算: *
     除法运算: / (结果中只保留整数)
     求模(取余)运算: %

    [root@lala ~]# x=35
    [root@lala ~]# y=16
    [root@lala ~]# expr $x + $y
    51
    [root@lala ~]# expr $x+$y
    35+16
    [root@lala ~]# expr $x - $y
    19
    [root@lala ~]# expr $x * $y
    expr: 语法错误
    [root@lala ~]# expr $x \* $y
    560
    [root@lala ~]# expr $x / $y
    2
    [root@lala ~]# expr $x % $y
    3
    [root@localhost ~]# expr $y % $x
    16                                                        取余数  就是 16 / 35 除不开则 =除数本身
    如果变量值为小数了:
    [root@localhost ~]# x=7.5
    [root@localhost ~]# y=8.5
    [root@localhost ~]# expr $y + $x
    expr: 非整数参数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    Different trains are going somewhere better!

  • 相关阅读:
    【mysql】【win】Windows安装配置mysql
    喜报 | 擎创科技实力亮相2023科创会并荣获科技创新奖
    java多线程新
    ThreeJS 几何体顶点position、法向量normal及uv坐标 | UV映射 - 法向量 - 包围盒
    数据结构和算法之插入排序
    【Android笔记27】Android中的动画效果之属性动画
    CSS3-圆角边框border-radius 盒子阴影border-shadow
    房屋租赁管理系统的设计与实现
    Tomcat部署及优化
    Android webView JS 之间的交互
  • 原文地址:https://blog.csdn.net/qq_50573146/article/details/126435994