shell变量

264 阅读3分钟

变量赋值

双引号("")

主要起界定字符串的作用,特别是当要赋值的内容中包括空格时,必须要双引号括起来,其他情况可以省略

引用变量时,通常建议将变量包含在双引号中。因为这样可以防止除 $ , ` (反引号)和 \ (转义符)之外的其他特殊字符被重新解 释。

hello="A B  C  D" 

echo $hello # A B C D 

echo "$hello" # A B  C  D 

双引号内引用变量将会保留变量的空白符。当避免字符分割或者保留空白符出现问题时,需要用双引号包住变量

单引号('')

单引号会禁用掉(转义)变量引用,而保持原字符串,包含单引号时,需要使用'\''符号进行转义

反撇号(`)

反撇号用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。反撇号括起来的范围必须是能够执行的命令行。需要注意的是,使用反撇号难以在一行命令中实现嵌套命令替换操作,这时可以使用“$()”来代替反撇号操作,以解决嵌套的问题

[root@localhost ~]#rpm -qc $(rpm -qf $(which useradd))
/etc/default/useradd
/etc/login.defs
查询提高useradd命令程序的软件包所安装的配置文件位置

变量追加值

格式

变量名+=追加值

[root@centos8 ~]#TITLE=CTO
[root@centos8 ~]#TITLE+=:wang
[root@centos8 ~]#echo $TITLE
CTO:wang

[root@centos8 ~]PATH+=:/mnt
[root@centos8 ~]PATH+=/data

read命令

从键盘输入内容为变量赋值

格式: read 变量名

以空格为分隔符,将读入的各字段挨个赋值指定的变量(多余的内容赋值给最后一个变量)。若指定的变量只有一个,则将整行的内容赋值给此变量。

常用选项:

  • -p:后面跟提示信息,即在输入前打印提示信息。
  • -s:安静模式,在输入字符时不再屏幕上显示,例如密码。
  • -t:后面跟秒数,定义输入字符的等待时间。
  • -n:后跟一个数字,定义输入文本的长度。
  • -a:后跟一个变量,该变量会被认为是个数组。
[root@localhost ~]# read -p "请输入您的年龄:" age  
请输入您的年龄:20  
[root@localhost ~]# echo $age  20

变量的作用范围

局部变量

定义变量: 变量名=变量值

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

查看变量:

  • echo $变量名:查看单个变量
  • set:查看所有变量,包括局部变量和环境变量

取消变量: unset 变量名

作用范围: 仅在当前shell环境中有效,无法在子shell环境中使用。

可以通过内部命令export将指定的变量为全局变量,使用户定义的变量在所子shell环境中可以继续使用

  1. 格式1:export 变量名 //可以指定多个已定义的变量导出为全局变量,变量之间以空格分隔
  2. 格式2:export 变量名=变量值 //直接新建一个全局变量

变量运算

expr 整数运算

直接返回运算结果。

[root@localhost ~]# a=1  
[root@localhost ~]# b=2  
[root@localhost ~]# expr $a + $b  
3

需要指定变量接收结果时 用$( )和反撇号,可以调用命令的执行结果。配合echo打印变量

[root@localhost ~]# i=$(expr 2 + 5 * 3)  
[root@localhost ~]# echo $i  
17  
[root@localhost ~]# m=`expr 1 + 2`  
[root@localhost ~]# echo $m  
3

let 和 (( ))

let var=算术表达式 和  ((var=算术表达式))  效果等同。

必须指定变量接收运算结果。两者都不返回结果,需要借助echo命令。

[root@localhost ~]# a=30  
[root@localhost ~]# b=20  
[root@localhost ~]# let cc=$a+$b     //加法  
[root@localhost ~]# echo $cc  
50

[root@localhost ~]# ((z=1+2))  
[root@localhost ~]# echo $z  
3

$[ ]$(( ))

$[ ] 和 $(( ))效果相同,且都支持对变量直接进行运算。配合echo直接打印结果

[root@localhost ~]# a=2  
[root@localhost ~]# b=5  
[root@localhost ~]# echo $((a+b)) 
7  
[root@localhost ~]# echo $[a*b]  
10  

需要指定变量接收结果,直接指定变量。配合echo打印变量

[root@localhost ~]# n=$((a+b))  
[root@localhost ~]# echo $n
7  
[root@localhost ~]# m=$[a*b]  
[root@localhost ~]# echo $m
10

特殊变量

只读变量

我们在定义shell变量时,默认定义的变量是可以被修改的,但有一种变量是不能修改的,就是只读变量。

只读变量只能被赋值一次。只读变量在取得初始值之后,只能进行读取操作,不能重新赋值或删除。

定义变量:

  • 第一步:name=value # 定义一个变量
  • 第二步:readonly name # 使用 readonly 来修饰该变量 ,表明只读
 [root@localhost data]# year=2022       //定义一个变量year         
 [root@localhost data]# readonly year   //使用 readonly 修饰该变量 ,表明只读
 [root@localhost data]# echo $year
 2022
 [root@localhost data]# year=2000      //无法重新赋值
 -bash: year: 只读变量
 [root@localhost data]# unset year     //无法使用unset删除
 -bash: unset: year: 无法反设定: 只读 variable

位置变量

位置变量也称为位置参数。

使用$n表示,n为数字序列号,且必须为整数。

如:$1$2、…、$9${10}${11}

两位数需要加花括号{},不然$10会被识别为:$1和0 。

示例:

 [root@localhost ~]# cat weizhi.sh
 #!/bin/bash
 echo "$1"    #显示位置1的参数
 echo "$2"    #显示位置2的参数
 echo "$3"    #显示位置3的参数
 ​
 [root@localhost ~]# bash weizhi.sh aaa bbb ccc
 aaa      //对应$1
 bbb      //对应$2
 ccc      //对应$3

预定义变量

预定义变量是系统定义好的变量,用来保持脚本程序的执行信息。

可以直接使用这些变量,不能直接为这些变量赋值。

变量作用
$?表示前一条命令执行后的返回状态。返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常。
$*表示所有位置参数的内容。当整体返回。(将输入的参数作为一个单词)
$@表示所有位置参数的内容。当个体返回。可作为数组。(将参数内容分割成n份,每份作为独立个体)
$#表示命令行中位置参数的总个数。
$0表示当前脚本名称(如果是软链接,显示当前软链接文件名)。
$_表示在此之前执行的命令或脚本的最后一个参数。
$$获取当前进程的PID。

$*$@的区别:

  • 不加双引号的话,$*$@ 都代表脚本后面跟的所有参数。
  • 加上双引号的话,"$*"会把所有参数当作一个整体去看待(此时参数数量为1),"$@"会把脚本后面跟的每一个参数当作一个个体去看待。

示例:

1)测试 $? 的作用。

 [root@localhost ~]# ls /opt
 rh
 [root@localhost ~]# echo $?      //返回0表示执行正常
 0                          
 [root@localhost ~]# ls /xxx
 ls: 无法访问/xxx: 没有那个文件或目录
 [root@localhost ~]# echo $?      //返回非0表示执行出现异常
 2
 ​
 [root@localhost ~]# ls /opt /xxx
 ls: 无法访问/xxx: 没有那个文件或目录
 /opt:
 rh
 [root@localhost ~]# echo $?
 2

环境变量

系统内置环境变量

1、由系统提前创建,用来设置用户的工作环境。

2、使用env命令查看所有环境变量:

 [root@localhost ~]# env    //查看所有环境变量,这里只截取部分进行展示
 XDG_SESSION_ID=1
 HOSTNAME=localhost.localdomain
 SELINUX_ROLE_REQUESTED=
 TERM=xterm
 SHELL=/bin/bash
 HISTSIZE=1000
 SSH_CLIENT=192.168.72.100 55445 22
 SELINUX_USE_CURRENT_RANGE=
 SSH_TTY=/dev/pts/0
 USER=root

3、需要记住的常用环境变量:

  • $PATH 表示可执行文件的默认路径
  • $USER 表示用户名称
  • $HOME 表示用户的宿主目录
  • $LANG 表示语言和字符集
  • $PWD 表示当前所在工作目录
 [root@localhost ~]# echo $PATH
 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
 [root@localhost ~]# echo $USER
 root
 [root@localhost ~]# echo $HOME
 /root
 [root@localhost ~]# echo $LANG
 zh_CN.UTF-8
 [root@localhost ~]# echo $PWD
 /root

4、环境变量的特性:

  • 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。
  • 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程。
  • 一般只在系统配置文件中使用,在脚本中较少使用。

设置环境变量3种方法

  1. 在/etc/profile文件中添加变量【对所有用户生效(永久的)】
    用VI在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久的”。
    例如:编辑/etc/profile文件,添加CLASSPATH变量
[root@localhost ~]# vi /etc/profile  
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib  

注:修改文件后要想马上生效还要运行# source /etc/profile不然只能在下次重进此用户时生效。

  1. 在用户目录下的.bash_profile文件中增加变量【对单一用户生效(永久的)】
    用VI在用户目录下的.bash_profile文件中增加变量,改变量仅会对当前用户有效,并且是“永久的”。
    例如:编辑guok用户目录(/home/guok)下的.bash_profile
[root@localhost ~]$ vi /home/guok/.bash.profile  
添加如下内容:  
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib  

注:修改文件后要想马上生效还要运行$ source /home/guok/.bash_profile不然只能在下次重进此用户时生效。

  1. 直接运行export命令定义变量【只对当前shell(BASH)有效(临时的)】
    在shell的命令行下直接使用[export变量名=变量值]定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。

生成随机数

使用 echo $[RANDOM%n] 可以生成随机数,n为正整数。

对 n 取余数的范围是 [0,n-1]。

  • echo $[RANDOM%10]生成的随机数范围为 [0,9]
  • 如果希望包含10的话,可以echo $[RANDOM%11],则随机数范围为 [0,10]。
  • 如果希望随机数范围都为正整数,即不包含0的话,可以echo $[RANDOM%10+1],此时随机数范围为[1,10]。