一文讲清楚shell 中的变量是怎么回事

目录

变量和引用

一, 什么是变量

二, 根据数据类型分类

三, 根据作用域分类

 1、环境变量

 2、普通变量

四, 变量的定义

 1、变量定义示例:变量名=变量值

  2、位置参数和预定义变量

五, shell中的引用

六,变量的运算


变量和引用

一, 什么是变量

       顾名思义,变量就是程序设计语言中的一个可以变化的量,当然,可以变化的是变量的值。几乎所 有的程序设计语言中都有定义变量,并且其涵义也大同小异。从本质上讲,变量就是在程序中保存用户 数据的一块内存空间,而变量名就是这块内存空间的地址

       在程序的执行过程中,保存数据的内存空间的内容可能会不断地发生变化,但是,代表内存地址的 变量名却保持不变。

环境变量全部用大写字母表示

变量:变量名=值(可不可以是一个表达式, 命令执行的结果)

        

二, 根据数据类型分类

         Shell是一种动态类型语言和弱类型语言,即在Shell中,变量的数据类型毋需显示地声明,变量的数据类型会根据不同的操作有所变化。准确地讲,Shell中的变量是不分数据类型的,统一地按照字符串存储。但是根据变量的上下文环境,允许程序执行一些不同的操作,例如字符串的比较和整数的加减等等。

var_data=1              遇到有空格连接的字符串,空格以及空格后面的无法输出

var_data2='1'         单引号里面的内容原样输出

var_data3="1"        可以把空格打印出来,双引号整体输出

var_data4=`pwd`   反引号表示执行这条命令,获取这条命令的执行结果

Var_data5=$(pwd)

什么是弱类型语言、强类型语言?

       强类型和弱类型主要是站在变量类型处理的角度进行分类的。强类型是指不允许隐式变量类型转换,弱类型则允许隐式类型转换。

       强类型语言,当你定义一个变量是某个类型,如果不经过代码显式转换(强制转化)过,它就永远都是这个类型,如果把它当做其他类型来用,就会报错

       弱类型语言,你想把这个变量当做什么类型来用,就当做什么类型来用,语言的解析器会自动(隐 式)转换。

比如:

C语言定义变量,int+变量名,实则前面的int就是给变量内存划分了等级,int定义整型所以空间里 只能存放整型,这就是强类型。php、C#和Python等都是强类型语言。

可以使用declare定义变量的类型:declare attribute variable

注:declare命令还可输出所有的变量、函数、整数和已经导出的变量

-p:显示所有变量的值

-i:将变量定义为整数,在之后就可以直接对表达式求值,结果只能是整数。如果求值

     失败或者不是整 数,就设置为0。

 -r:将变量声明为只读变量。只读变量不允许修改,也不允许删除。(也可使用readonly

      定义只读变量)

-a:变量声明为数组变量。但这没有必要,所有变量都不必显示定义就可以用作数组。

      事实上,在某 种意义上,似乎所有变量都是数组,而且赋值给没有下标的变量与

      赋值给下标为0的数组元素相同。

 -f:显示所有自定义函数,包括名称和函数体。

 -x:将变量设置成环境变量。可使用+x将变量变成非环境变量

(环境变量必须使用declare -x   或者  export导出才称为环境变量 )

三,根据作用域分类

根据作用域可将变量分为环境变量(全局变量)和普通变量(局部变量)

 1、环境变量

      环境变量也可称为全局变量,可以在创建它们的shell及其派生出来的任意子进程shell中使用(su - 切换用户会读取新的环境变量),环境变量又可分为自定义环境变量和bash内置的环境变量。

命令行定义一个环境变量并用export命令导出,切换用户访问不到,新建连接也访问不到

(1)自定义环境变量

       一般是指用export内置命令导出的变量,用于定义shell的运行环境,保证shell命令的正确执行。环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,即该环境变量只在当前 shell和子shell中有效。如果希望永久保存环境变量,可以在配置文件中设置。

①用户的环境变量配置(non-login shell)

~/.bash_profile或~/.bashrc

②全局环境变量的配置(login shell)

 /etc/bashrc、/etc/profile文件或者/etc/profile.d目录(额外配置文件)中定义。

文件之间的联系:

在/etc/profile有一条:    .   /etc/bashrc -》 要去执行/etc/bashrc

                                    (以".  " 的方式执行不会产生子进程)

                                               /etc/profile.d/*.sh  . "$i" -> 也要去执行/etc/profile.d/*.sh的文件

在/etc/bashrc -> 会执行/etc/profile.d/*.sh文件

在~/.bash_profile中:      . ~/.bashrc

在~/.bashrc中:           . /etc/bashrc

1.如果我要配置一个只针对root用户的环境变量,应该配置在什么地方

~/.bash_profile或者~/.bashrc

2.如果我要配资一个针对所有用户的环境变量,应该配置在什么地方

/etc/profile或者/etc/bashrc 或者在/etc/profile.d目录中去定义.sh文件

定义环境变量的方式:

1. export mydata2=mydata2

2. mydata=mydata;export mydata

3. declare -x mydata3=mydata3

小练习:

1,进入到当前用户家目录下的配置文件中配置环境变量

[root@wangjingjing 0130]# vim ~/.bash_profile

mydata1=mydata1

export mydata1

export mydata2=mydata2

declare -x mydata3=mydata3

2,直接访问会出现访问不到,因为登录时,配置文件已经加载过

[root@wangjingjing 0130]# echo $mydata1

[root@wangjingjing 0130]# echo $mydata2

[root@wangjingjing 0130]# echo $mydata3

3,建立新的连接会重新加载配置文件可以直接访问到

[root@wangjingjing 0130]# echo $mydata1

mydata1

[root@wangjingjing 0130]# echo $mydata2

mydata2

[root@wangjingjing 0130]# echo $mydata3

mydata3

[root@wangjingjing 0130]#

4,Su -  会切换环境变量可以直接访问到

[root@wangjingjing 0130]# su -

[root@wangjingjing ~]# echo $mydata1

mydata1

[root@wangjingjing ~]# echo $mydata2

mydata2

[root@wangjingjing ~]# echo $mydata3

mydata3

5,在当前环境去访问(不产生子进程),source和.

[root@wangjingjing ~]# source ~/.bash_profile

[root@wangjingjing ~]# echo $mydata3

mydata3

[root@wangjingjing ~]# echo $mydata2

mydata2

[root@wangjingjing ~]# echo $mydata1

mydata1

[root@wangjingjing ~]#

 注意:按照系统规范,所有环境变量的名字均采用大写形式。在将环境变量应用于用户进程程序之前,都应该用 命令export导出。

 有一些环境变量,比如HOME,PATH,SHELL,UID,USER等,在用户登录前就已经被/bin/login程序设置 好了,通常环境变量被定义并保存在用户家目录下的.bash_profile文件或全局的配置文件/etc/profile 中。

(2)bash内置的环境变量

        shell内置的环境变量是所有的shell程序都可以使用的变量。shell程序在运行时,都会接收一组变量 来确定登录用户名、命令路径、终端类型、登录目录等,这组变量就是环境变量。环境变量会影响到所 有的脚本的执行结果。

注:可使用env查看环境变量

1,HOME 用户主目录的路径名,是cd命令的默认参数

[root@wangjingjing ~]# echo $HOME

/root

[root@wangjingjing ~]# su redhat

[redhat@wangjingjing root]$ echo $HOME

/home/redhat

[redhat@wangjingjing root]$ exit

exit

[root@wangjingjing ~]#

2,IFS 定义shell使用的分隔符(默认是空行)

[root@wangjingjing ~]# echo $IFS

[root@wangjingjing ~]#

[root@wangjingjing ~]# echo "$IFS 123"

         

 123

[root@wangjingjing ~]#

3,LOGNAME 当前的登录名

[root@wangjingjing ~]# echo $LOGNAME

root

[root@wangjingjing ~]# su redhat

[redhat@wangjingjing root]$ echo $LOGNAME

redhat

2、普通变量

        普通变量也可称为局部变量,与全局变量相比,局部变量的使用范围较小,通常仅限于某个程序段访 问,例如函数内部。在Shell语言中,可以在函数内部通过local关键字定义局部变量,另外,函数的参数 也是局部变量。

四, 变量的定义

        在Shell中,通常情况下用户可以直接使用变量,而毋需先进行定义,当用户第一次使用某个变量名 时,实际上就同时定义了这个变量,在变量的作用域内,用户都可以使用该变量。

 1、变量定义示例:变量名=变量值

#!/bin/bash #定义变量a

a=1

 #定义变量b

b="hello"

#定义变量c

c="hello world"

#定义备份路径

bak_dir=/data/backup

#把一个命令的结果赋值变量

变量名=`ls`

变量名=$(ls)

注意:

(1)“=”前后不能有空格

(2)字符串类型建议用引号括起来,尤其是特殊字符或有空格

 引用变量:$变量名 或者${变量名}

[root@wangjingjing ~]# data=1

[root@wangjingjing ~]# echo $data

1

[root@wangjingjing ~]# echo ${data}

1

[root@wangjingjing ~]#

 查看变量:echo $变量名,set(可查看所有变量:包括自定义变量和环境变量),env

                  显示全局变量, declare输出所有的变量、函数、整数和已经导出的变量。

[root@wangjingjing ~]# set | grep mydata

mydata1=mydata1

mydata2=mydata2

mydata3=mydata3

[root@wangjingjing ~]# env | grep mydata

mydata2=mydata2

mydata3=mydata3

mydata1=mydata1

[root@wangjingjing ~]# declare | grep mydata

mydata1=mydata1

mydata2=mydata2

mydata3=mydata3

[root@wangjingjing ~]#

 取消变量:unset 变量名

[root@wangjingjing ~]# data=1

[root@wangjingjing ~]# echo $data

1

[root@wangjingjing ~]# unset data

[root@wangjingjing ~]# echo $data

[root@wangjingjing ~]#

 作用范围:仅在当前shell中有效

注:可使用export指令将变量转换成环境变量

2、位置参数和预定义变量

许多情况下,Shell脚本都需要接收用户的输入,根据用户输入的参数来执行不同的操作。 从命令行传递给Shell脚本的参数又称为位置参数,Shell脚本会根据参数的位置使用不同的位置参数变量 读取它们的值。

练习:

建立一个脚本:args_script.sh

bash args_script.sh 传递6个参数

1.获取参数的个数

2.获取所有的参数

3.获取1,3,5这个三个位置的参数

4.获取脚本的名字

1,打开文件编辑并保存退出

[root@wangjingjing ~]# vim args_script.sh

echo "args count is $#"

echo "all args(@) are $@"

echo "all args(*) are $*"

echo "arg 1 is $1"

echo "arg 3 is $3"

echo "arg 5 is $5"

echo "script name is $0"

 

2,执行文件,传入参数

[root@wangjingjing ~]# bash args_script.sh 1 2 3 4 5 6

args count is 6

all args(@) are 1 2 3 4 5 6

all args(*) are 1 2 3 4 5 6

arg 1 is 1

arg 3 is 3

arg 5 is 5

script name is args_script.sh

 

$*和$@的区别示例:   整体    单独个体

[root@wangjingjing ~]# set -- 1 2 3 4

[root@wangjingjing ~]# for i in "$@";do echo $i;done;

1

2

3

4

[root@wangjingjing ~]# for i in "$*";do echo $i;done;

1 2 3 4

[root@wangjingjing ~]#

五, shell中的引用

 在bash中有很多特殊字符,这些特殊字符就具有特殊含义。引用就是通知shell将这些特殊字符当作普通 字符来处理。

六,变量的运算

与其他的程序设计语言一样,shell也有很多运算符。

加法:

[root@wangjingjing ~]# data=$((1+2))

[root@wangjingjing ~]# echo $data

3

减法:

[root@wangjingjing ~]# data=$((1-2))

[root@wangjingjing ~]# echo $data

-1

乘法:

[root@wangjingjing ~]# data=$((1*2))

[root@wangjingjing ~]# echo $data

2

除法:

[root@wangjingjing ~]# data=$((1/2))

[root@wangjingjing ~]# echo $data

0

幂次方:

[root@wangjingjing ~]# data=$((2**2))

[root@wangjingjing ~]# echo $data

4

加等;其它等与之类似:

[root@wangjingjing ~]# data=1

[root@wangjingjing ~]# ((data+=1))

[root@wangjingjing ~]# echo $data

2

自增(++data)   自减与之相同:

[root@wangjingjing ~]# data=1

[root@wangjingjing ~]# ((data2=++data))              data加一后赋值给data2

[root@wangjingjing ~]# echo $data

2

[root@wangjingjing ~]# echo $data2

2

自增(data++):

[root@wangjingjing ~]# data=1

[root@wangjingjing ~]# ((data2=data++))       把data赋值给data2后,data加一

[root@wangjingjing ~]# echo $data

2

[root@wangjingjing ~]# echo $data2

1

二进制

位运算(左移变大,右移变小)

左移:

[root@wangjingjing ~]# echo $((8<<2))

32

右移:

[root@wangjingjing ~]# echo $((8>>2))

2

&

[root@wangjingjing ~]# echo $((8&8))

8

|

[root@wangjingjing ~]# echo $((8|8))

8

 

异或^(相同为0,不同为1)

[root@wangjingjing ~]# echo $((8^8))

0

[root@wangjingjing ~]# echo $((1^2))

3

用作整数运算:(() -> (())中变量不需要使用$

                                    echo  $(())

                                let:  let 变量名=运算表达式

                              echo $变量名

                                expr:  expr  1 + 1

                                           expr  1 '+' 1

                                $[]:  使用: echo $[1+1]

                                declare:  declare -i data=2+3

                                                  echo $data

用作小数的运算   echo  " 计算"  |  bc

1,() -> (())中变量不需要使用$

                                    echo  $(())

[root@wangjingjing ~]# echo $((1+1))

2

   2,   let:  let 变量名=运算表达式

                              echo $变量名

[root@wangjingjing ~]# let data+1+1

[root@wangjingjing ~]# echo $data

2

3, expr:  expr  1 + 1

               expr  1 '+' 1

               expr $num + $ num2

expr也可以检查两个值是否为数字,非数字无法运算,会报错

[root@wangjingjing ~]# expr 1 + 1

2

[root@wangjingjing ~]# expr 1 "+" 1

2

[root@wangjingjing ~]# num1=1

[root@wangjingjing ~]# num2=a

[root@wangjingjing ~]# expr $num1 + 1 &> /dev/null

[root@wangjingjing ~]# echo $?

0

[root@wangjingjing ~]# expr $num2 + 1 &> /dev/null

[root@wangjingjing ~]# echo $?

2

4bc 

echo  " 表达式"  |  bc

[root@wangjingjing ~]# echo "1+1" | bc

2

直接执行bc命令是交互式的

5,  $[]:  使用: echo $[1+1]

[root@wangjingjing ~]# echo $[1+4]

5

6,declare -I 变量=运算表达式

   echo $变量

[root@wangjingjing ~]# declare -i data=8+9

[root@wangjingjing ~]# echo $data

17

练习:

定义两个变量:num1=10和num2=2
使用(()): 计算num1 + num2的值并输出
使用let: 计算num1 * num2的值输出
使用expr: 计算num1 对 num2执行或的位运算
使用$[]: 计算 num2的num1次方值
declare: 计算 num1 除以 num2的值


定义两个变量:num1=10和num2=2

[root@wangjingjing ~]# num1=10

[root@wangjingjing ~]# num2=2

1,使用(()): 计算num1 + num2的值并输出

[root@wangjingjing ~]# echo $((num1+num2))

2,使用let: 计算num1 * num2的值输出

[root@wangjingjing ~]# let data=num1*num2

[root@wangjingjing ~]# echo $data

3,使用expr: 计算num1 对 num2执行或的位运算

[root@wangjingjing ~]# expr $num1 "|" $num2

4,使用$[]: 计算 num2的num1次方值

[root@wangjingjing ~]# echo $[num2**num1]

5,declare: 计算 num1 除以 num2的值

[root@wangjingjing ~]# declare -i data=num1/num2

[root@wangjingjing ~]# echo $data

1,返回变量的内容

2,求字符串的长度

[root@wangjingjing ~]# echo ${#date}

3,截取字符串,截取3(输出不包括3)之后的字符串

[root@wangjingjing ~]# echo ${date:3}

4,从那个位置开始截取,以及截取的字符串的长度为多长

[root@wangjingjing ~]# echo ${date:2:2}

5,从最左边到最右边匹配到并删除最短的字符串

[root@wangjingjing ~]# echo ${data#*/}

6,从最左边到最右边匹配到并删除最长的字符串(最短作比较)

7,从最右到最左边匹配到并删除最短的字符串(最长作比较)

[root@wangjingjing ~]# echo ${data%/*}

8,从最右边到最右边匹配到并删除最长的字符串(最短作比较)

9,替换只替换第一个

10,替换所有,对原来的变量并没有改变

练习:

path=/data/data1/data2.txt

[root@wangjingjing ~]# path=/data/data1/data2.txt

    去获取它所在的目录

[root@wangjingjing ~]# echo ${path%/*}

    去获取文件的名字

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值