变量和引用

目录

变量和引用

2.1.深入认识变量

2.1.1.什么是变量

2.1.2.变量的名称

2.1.3.变量的类型

2.1.4.变量的定义

2.1.5自定义变量

2.1.6.环境变量(全局变量)

2.1.7 shell 环境变量存储的文件

2.1.8.位置变量

declare命令

2.2.变量赋值和作用域

2.2.1.显示赋值:变量名=变量值

2.2.2.read 从键盘读入变量值

2.2.3.变量和引号

2.2.4.变量的作用域

2.2.5.变量的运算

2.2.6.shell特殊扩展


变量和引用

2.1.深入认识变量

2.1.1.什么是变量

        变量是在程序中保存用户数据的一段内存存储空间,变量名是内存空间的首地址

        变量三要素:名称、类型、值

2.1.2.变量的名称

        组成: 字母数字下划线组成,不能以数字开头
        变量名称的长度,shell没有明确规定,但是为了增加可读性,建议使用较短的、见名知意的名称命名

则:
        首字符必须为字母:a-z,A-Z
        中间不能由空格,可以使用下划线 ()
        不能使用标点符号
        不能使用bash中关键字,输入help查看bash的保留字

例:下面的变量名都是很好的选择

        [root@server ~]# JAVA_HOME=/usr/bin/jvm/jre-1.6.0-openjdk.x86_64

        [root@server ~]# SUM=0
        [root@server ~]# back_up=/root

2.1.3.变量的类型

        原则:shell是一种动态类型语言和弱类型语言,变量是不分数据类型的,统一都使用字符串存储,但根据变量的上下文环境,允许程序执行一些不同的操作,如:比较、整数加减

        shell的变量数据类型

[root@server ~]# vim test1.sh
        x=123

        let x+=1

        echo "x=$x"
[root@server ~]# bash  test1.sh

        x=124

2.1.4.变量的定义

        原则:直接使用,不需要变量声明。格式:变量名=变量的值
例:

[root@server ~]# vim test2.sh

        a=1

        b="hello"

        c="hello world"

        bak_dir=/mnt
[root@server ~]# bash test2.sh 

前后不能收空格
[root@server ~]#
a= 3
        bash: 3: command not found...

[root@server ~]# b =5

        bash: b: command not found...
字符串类型建议使用双引好作为定界符引起,尤其是字符串中有空格
[root@server ~]#
stu_name=zhang

        sanbash: san: command not found...

[root@server ~]# stu_name="zhang san'

[root@server ~]# stu_name='zhang san

2.1.5自定义变量

        概念:上述以赋值形态形成的变量定义形式称为自定义变量
        引用变量的值
        $变量名
        ${表达式或变量名)

例:

        [root@server ~]# a=1024
        [root@server ~]# echo $a

        1024
        [root@server ~]# echo {$a}
        {1024}
        [root@server ~]# echo ${a}
        1024

查看变量

[root@server ~]# set |more |grep a=

2.1.6.环境变量(全局变量)

        环境变量又称为全局变量,可以在任意子shell生效,环境变量又分为自定义环境变量和bash内置的环境变量,用户退出命令后改变量会丢失,若需要永久保存就必须写在文件中

        定义环境变量

例:

bash自带的全局变量:

[root@server ~]# vim /etc/profile
[root@server ~]# echo $PATH 

/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@server ~]# echo $SHELL
/bin/bash      

自定义全局变量 :

        法一:export   环境变量=值

        [root@server ~]#  export back_dir1=/home/fox

        法二:

                变量名=值

                export 变量名

        [root@server ~]# NAME=zhangsan
        [root@server ~]# export NAME

 

        法三:declare    -X   变量名=值

        [root@server ~]# declare -x AGE=20

显示全局变量:

        [root@server ~]# env               

        [root@server ~]# printenv 

        [root@server ~]# export

        注意:以上三者效果一样

        注意:以上定义的环境变量都是临时的,重启后会失效,若要永久生效,则需要写入到配置文件中

2.1.7 shell 环境变量存储的文件

bash shell 初始化文件有: /etc/profile、 ~/.bash_profil、 ~/bash_login、~/.profile、 ~/.bashrc、/etc/bashrc

        /etc/profile: 存放一些全局 (共有)变量,不管哪个用户,登录时都会读取该文件。通常设置一些Shell变量PATH,USER,HOSTNAME和HISTSIZE等

        ~/.bash_profile: (每个账户都有,只针对当前账户)每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时该文件仅仅执行一次,默认情况下,此文件通过脚本执行同目录下用户的.bashrc文件

        ~/.bashrc: 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取(每个账户都有,只针对当前账户,当前账户专用的变量)
        /etc/bashrc: 为每一个运行bash shell的用户执行此文件当bash shell被打开时,该文件被
读取
/etc/inputrc文件为特定的情况处理键盘映射执行顺序:

        /etc/profile-->/etc/profile.d/*.sh--> ~/.bash profile -->/etc/bashrc-.>~/bashrc

bash内置环境变量

影响所有的脚本的执行结果。

变量说明
PATH命令的搜索路径,以冒号作为分隔符
HOME用户的家目录的路径,是cd命令的默认参数
COLUMNS命令行编辑模式下可使用命令的长度
HISTFILE命令历史的文件路径
HISTFILESIZE命令历史中包含的最大行数
HISTSIZEhistory命令输出的记录数
LOGNAME当前用户的名字
SHELL当前使用的shell
PWD当前的工作目录

2.1.8.位置变量

        概念:当一条命令或脚本执行时,后面可以跟多个参数,可以使用位置变量来表示该参数

 bash  testl.sh hello world 123 456

        当执行test1.sh 脚本时,第一个参数为hello到第四个参数可以使用特殊的符号表示,如:$1$2$3.....

        常见的位置变量
                $0 : 脚本名
                $1-$9 : 1-9个参数
                ${10} :10以上的参数需要大花括号括起
                   $* : 所有参数
                   $@ : 所有参数
                $#:参数个数
                $$:当前进程的PID
                $! : 上一个后台进程的PID
                $? : 上一个命令的返回值状态码,0为成功
[root@server ~]# vim test3.sh


echo "第一个位置的参数是:$1"
echo "第二个位置的参数是:$2"
echo "第四个位置的参数的:$4"
echo "所有参数是:$*"
echo "所有参数的:$@"
echo "参数个数是:$#"
echo "当前脚本的进程PID值:$$"
echo "当前脚本的文件名$0"

[root@server ~]# bash  test3.sh  a b c d e f g 

$* 与 $@区别:

        当S* 和 S @没有被引用的时候,它们确实没有什么区别,都会把位置参数当成一个个体,"$*"会把所有位置参数当成一个整体(或者说当成一个单词),如果没有位置参数,则"S* "为空,如果有两个位置参数并且IFS为空格时,"$*"相当于"$1 $2"

        "$@"会把所有位置参数当成一个单独的字段,如果没有位置参数 (S#为0),侧”S@"展开为空(不是空字符串,而是空列表),如果存在一个位置参数,则"S@"相当于"S1",如果有两个参数,则"S@"相当于"$1" "$2"等等

declare命令

declare为shell指令,在第一种语法中可用来声明变量并设置变量的属性([rix]即为变量的属性),在第二种语法中可用来显示shell函数。若不加上任何参数,则会显示全部的shell变量与函数(与执行set指令的效果相同)。

 语法:declare [+/-][rxi][变量名称=设置值] 或 declare -f
  • +/-  "-"可用来指定变量的属性,"+"则是取消变量所设的属性。

  • -f  仅显示函数。

  • r  将变量设置为只读。

  • x  指定的变量会成为环境变量,可供shell以外的程序来使用。

  • i  [设置值]可以是数值,字符串或运算式。

声明整数型变量

 # declare -i ab //声明整数型变量
 # ab=56 //改变变量内容
 # echo $ab //显示变量内容
 56

改变变量属性

 # declare -i ef //声明整数型变量
 # ef=1  //变量赋值(整数值)
 # echo $ef //显示变量内容
 1
 # ef="wer" //变量赋值(文本值)
 # echo $ef 
 0
 # declare +i ef //取消变量属性
 # ef="wer"
 # echo $ef
 wer

设置变量只读

 # declare -r ab //设置变量为只读
 # ab=88 //改变变量内容
 -bash: ab: 只读变量
 # echo $ab //显示变量内容
 56

声明数组变量

 # declare -a cd='([0]="a" [1]="b" [2]="c")' //声明数组变量
 # echo ${cd[1]}
 b //显示变量内容
 ​
 # echo ${cd[@]} //显示整个数组变量内容
 a b c

显示函数

 # declare -f
 command_not_found_handle () 
 { 
   if [ -x /usr/lib/command-not-found ]; then
     /usr/bin/python /usr/lib/command-not-found -- $1;
     return $?;
   else
     if [ -x /usr/share/command-not-found ]; then
       /usr/bin/python /usr/share/command-not-found -- $1;
       return $?;
     else
       return 127;
     fi;
   fi
 }

2.2.变量赋值和作用域

2.2.1.显示赋值:变量名=变量值

[root@server ~]# ip1=192.168.17.128
[root@server ~]# school="PeKing University"
[root@server ~]# today1=`date +%F`                                                                                              [root@server ~]# today2=$(date +%F)                                                                                     [root@server ~]# echo $ip1

192.168.17.128
[root@server ~]# echo $school
PeKing University
[root@server ~]# echo $today1
2023-12-04
[root@server ~]# echo $today2 
2023-12-04                    # 由此得出   ` ` 等于 $()

2.2.2.read 从键盘读入变量值

        read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量

格式:     read    -参数    变量名

参数:

        -p“提示语句:” 屏幕打印出一行提示语句

        -n数字:当输入的字符数目达到预定数目时,自动退出,并将输入的数据赋值给变量,如:n1,只要接受到一个字符就退出。只要按下一个字符进行回答,read命令立即接受输入并将其传给变量。无需按回车键

        -t 等待时间:计时输入,使用read命令存在着潜在危险。脚本很可能会停下来一直等待用户的输入。如果无论是否输入数据脚本都必须继续执行,那么可以使用-t选项指定一个计时器。t选项指定read命令等待输入的秒数。当计时满时,read命令返回一个非零退出状态关闭回显,使read命令中输入的数据不显示在监视器上 (实际上,数据是显示的,只是

        -s:read命令将文本颜色设置成与背景相同的颜色)

 常用格式:

        read        变量名
        read        -p        “提示信息:”        变量名

例:

参数  -p:

[root@server ~]# read -p "Enter Numbers: " num 
Enter Numbers: 123             
[root@server ~]# echo $num
123
[root@server ~]# read -p "enter char (y/n):" num 
enter char (y/n):y
[root@server ~]# echo $num
y

参数  -t:
[root@server ~]# read -t 3 n1           # 等待三秒自动结束命令
[root@server ~]# read -s -p "请输入密码:" passwd 
请输入密码:[root@server ~]#            # 此处已经输入密码但默认不回显(无换行功能)

当read后没有变量接收值时:

[root@server ~]# read     
200
[root@server ~]# echo    $REPLY  # 当输入时没有变量接收则会存储到环境变量REPLY中
200

一次性输入多个值:

[root@server ~]# read t1 t2 t3 
132 344 "hehe"   
[root@server ~]# echo $t1 $t2 $t3
132 344 "hehe"
[root@server ~]# read t1 t2 t3 
132 344 hehe
[root@server ~]# echo $t1 $t2 $t3
132 344 hehe                                # 由此可得每一个值之间只需用空格隔开

2.2.3.变量和引号

双引号:(" ") 除了$、单引号、反引号、反斜线之外,其它被引起的内容保持字面意思
单引号:(' ') 所有字符保持字面意思,单引号括起来的字符都作为普通字符出现 .(少用)
反引号: (``)。反引号括起来的字串被Shell解释为命令,在执行时,Shell首先执行该命令,并以它的标准输出结果取代整个反引号(包括两个反引号)部分
反斜线: 转义符,屏蔽后面字符的特殊含义

        \n:  换行

        \t:   制表符

        \f:   分页(换页)

        \r:   回车但不换行

        \b:   退格  

         \\:   输出一个\

2.2.4.变量的作用域

        全局变量:全局变量定义在脚本中,也可以定义在函数中,

                        作用范围: 从定义的开始处到shel脚本结束或者被显示的去除

        局部变量:范围更小,仅限于某个程序段中,如: 函数、shell等,通过local关键字定义,注意函数的参数也是局部变量

全局变量和局部变量区别:

[root@server ~]# vim test5.sh

func()
{

        #输出全局变量v1的值
        echo "global variable vl is $v1"
        #定义局部变量v1
        local v1=2
        #输出局部变量v1的值
        echo "local variable vl is $v1"

}
#定义全局变量v1
v1=1
#调用函数
func
#输出全局变量v1的值
echo "global variable v1 is $v1!

[root@server ~]# bash test5.sh 
global variable vl is 1
local variable vl is 2
global variable v1 is 1!

2.2.5.变量的运算

运算符与命令:

        Shell 中常见的算术运算符号

算术运算符意义(*表示常用)
+、-加法(或正号)、减法(或负号)*

*、/、%

乘法、除法、取余(取模)*
**幂运算*
++、--增加及减少,可前置也可放在变量结尾*
!、&&、||逻辑非(取反)、逻辑与(and)、逻辑或(or)*
<、 <=、 >、>=比较符号(小于、小于等于、大于、大于等于)
==、!=、=比较符号(相等、不相等,对于字符串“=”也可以表示相当于)*
<<、>>向左移位、向右移位
~、|、&、^按位取反、按位异或、按位与、按位或

= 、+=、- =、*=、/=、%=

赋值运算符,例如a+=1相当于a=a+l,a-=1相当于a=a-1*

Shell 中常见的算术运算命令

运算操作符与运算命令意义
(())用于整数运算的常用运算符,效率很高
let用于整数运算,类似于“(0)”
expr可用于整数运算,但还有很多其他的额外功能(自带输出功能 )
bcLinux下的一个计算器程序(适合整数及小数运算)
$[]用于整数运算
awkawk 既可以用于整数运算,也可以用于小数运算
declare定义变量值和属性,-i 参数可以用于定义整形变量,做运算

例一:数字型

expr:

        [root@server ~]# expr  1 + 1                         # 缺点:运算符之间必须有空格
        2

        [root@server ~]# expr $a + $b                       # 需要加$ 
        3

(()):

        [root@server ~]# a=2
        [root@server ~]# b=6
        [root@server ~]# echo $((1+2))

        3
        [root@server ~]# echo $((a+b))
        8

        [root@server ~]# echo $((5/2))                             
        2
        [root@server ~]# echo $((5%2))
        1

        [root@server ~]# echo $((2.6+2))                            # 由此可见(())不支持小数
        -bash: 2.6+2:语法错误: 无效的算术运算符 (错误符号是 ".6+2")
        [root@server ~]# echo $[2.6+2]
        -bash: 2.6+2:语法错误: 无效的算术运算符 (错误符号是 ".6+2")

bc:(内置计算器)

[root@server ~]# bc   # 进入计算器                        # 注意:需使用quit 退出交互模式

bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
1+2
3
2-5
-3
6/2
3
1.5+2.3\
3.8
5>3
1
3>5
0
quit    # 退出交互模式

Shell 变量子串说明

表达式说明
${parameter}返回变量 $parameter 的内容
${#parameter}返回变量 $parameter 内容的长度(按字符)也适用于特殊变量
${parameter:offset}在变量 ${parameter}中,从位置 offset 之后开始提取子串到结尾
${parameter:offset:length}在变量 ${parameter}中,从位置offset 之后开始提取长度为 length的子串
${parameter#word}从变量 ${parameter} 开头开始删除,最短匹配的 word 子串
${parameter##word}从变量${parameter} 开头开始删除,最长匹配的 word 子串
${parameter%word}从变量${parameter} 结尾开始删除,最短匹配的 word 子串
${parameter%%word}从变量${parameter} 结尾开始删除,最长匹配的 word 子串
${parameter/pattern/string}使用string 代替第一个匹配的 pattern        
${parameter//pattern/string}使用 string 代替所有匹配的 pattern

例二:字符串型

使用“:”截取字符串          # 格式:${字符串:start :end}

返回变量长度
[root@localhost ~]# str1="hello world"
[root@localhost ~]# echo ${#str1}

11
变量截取 切片   :
指定起始位置,一直到结束
[root@localhost ~]# echo ${str1:1}
ello world
指定长度,不指定起始位置默认从开头开始
[root@localhost ~]# echo ${str1::3}
hel
指定起始位置和长度
[root@localhost ~]# echo ${str1:1:3}
ell
从右边第几个字符开始,及字符的个数
[root@localhost ~]# echo ${str1:0-1:1}
d
输出右边的几个字符
[root@localhost ~]# echo ${str1:0-5}
world
[root@localhost ~]# echo ${str1: -5}
world

使用%截取字符串,含义: 删除右边字符,保留左边字符

删除字符串: #
// 获取后缀名tar.gz
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename#*.}                开头最短匹配的
[root@localhost ~]# echo $file

tar.gz

// 获取后缀名gz
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename##*.}               # 开头最长匹配
[root@localhost ~]# echo $file

gz

//截取testfile.tar
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename%.*}                # 结尾最短匹配的
[root@localhost ~]# echo $file

testfile.tar

//截取testfile
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename%%.*}             # 结尾最长匹配
[root@localhost ~]# echo $file

testfile
//替换
[root@localhost ~]# echo ${str/is/IS}                     # 代替第一个匹配  

thIS is haha
[root@localhost ~]# echo ${str//is/IS}                    # 代替所有匹配
thIS IS haha

2.2.6.shell特殊扩展

Shell 的特殊扩展变量说明

表达式说明
${parameter:-word}

        如果 parameter 的变量值为空或未赋值,则会返回 word 字符串并代变量的值

        用途:如果变量未定义,则返回备用的值,防止变量为空值或因未定义而导致异常

${parameter:=word}

        如果 parameter 的变量值为空或未赋值,则设置这个变量值为 word,并返回其值位置变量和特殊变量不适用

        用途:基本同上一个Sparameter:-word},但该变量又额外给 parameter 变量赋值了

${parameter:?word}        如果 parameter 变量值为空或未赋值,那么word 字符串将被作为标准错误输出,否则输出变量的值。
        用途:用于捕提由于变量未定义而导致的错误,并退出程序
${parameter:+word}如果 parameter 变量值为空或未赋值,则什么都不做,否则word 字符串将替代变量的值

例:

-示例:用法1,如果parameter变量值为空或未赋值,则返回word字符串代替变量的值
//变量未赋值,输出为空。 (冒号可有可无)                  --------无值临时赋值
[root@localhost ~]# echo $var1

[root@localhost ~]# var2=${var1:-hello}
[root@localhost ~]# echo $var2

hello
-示例:用法2,如果parameter变量值有值,则变量返回parameter变量的值
[root@localhost ~]# var1="hello"
[root@localhost ~]# echo $var1

hello
[root@localhost ~]# var2=${var1:-world}
[root@localhost ~]# echo $var2

hello

=示例:用法1,如果parameter变量值为空或未赋值,则返回word字符串给变量赋值
注意和-,不同点在于-var1没有赋值,=将word赋值刚给var1              ---无值永久赋值
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var2=${var1:=world}
[root@localhost ~]# echo $var2

world
[root@localhost ~]# echo $var1
world

=示例:用法2,如果parameter变量值有值,则返回parameter变量的值
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var1=hello
[root@localhost ~]# var2=${var1:=world}                                    
[root@localhost ~]# echo $var2

hello
[root@localhost ~]# echo $var1
hello

?示例:
{parameter:?word}的作用是: 如果 parameter 变量值为空或未赋值, 那么 word 字符
串将被作为标准错误输出, 否则输出变量的值。
[root@localhost ~]# unset var1 var2
[root@localhost ~]# var2=${var1:?world}    
             ---无值作为提示信息报错,临时赋值
-bash: var1: world                                 expr  length $var1

[root@localhost ~]# unset var1 var2
[root@localhost ~]# var1=hello
[root@localhost ~]# var2=${var1:?world}
[root@localhost ~]# echo $var2

hello
[root@localhost ~]# echo $var1
hello

+示例:
${parameter:+word}的作用是: 如果 parameter 变量值为空或未赋值, 则什么都不
做, 否则 word 字符串将替代变量的值
[root@localhost ~]# unset var1                         ---无值什么都不做,有值则替换,临时替换
[root@localhost ~]# var2=${var1:+world}
[root@localhost ~]# echo $var2

[root@localhost ~]# unset var1 var2
[root@localhost ~]# var1=hello
[root@localhost ~]# var2=${var1:+world}
[root@localhost ~]# echo $var2

world
[root@localhost ~]# echo $var1
hello

shell特殊扩展应用案例:

删除7天前的过期数据备份。 

[root@localhost ~]# cat del.sh                     |   字符   -exec   |xargs   参数

find ${path:-/tmp} -name "*.bak" -type f -mtime +7 | xargs rm -f
如果没有定义path值,事先脚本中也没有设置变量:
[root@localhost ~]# cat del2.sh 
find ${path} -name "*.tar.gz" -type f -mtime +7 | xargs rm -f
这样就不会删除指定目录,而是删除脚本运行目录中的文件。

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱玩网络的小石

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值