一.概念
1.变量的定义:
变量即在程序运行过程中它的值是允许改变的量,
变量是用一串固定的字符来标志不固定的值的一种方法,
变量是一种使用方便的占位符,用于引用计算机内存地址,该地址可以存scripts运行时可更改的程序信息。
在shell中变量是不可能永久保存在系统中的,必须在文件中声明。
2.在shell脚本中变量的分类:
在shell中变量分为环境级变量,用户级变量,系统级变量
(1)环境级变量也可叫全局变量,只在当前shell中生效,shell关闭变量丢失,可以在创建他们的shell及派生出的子shell中使用(无需定义,直接可以使用,如:$UID)
相关命令:
set :输出所有变量
env:只显示全局变量
declare:输出所有变量,函数,整数等
[root@base1 ~]# export A=1
[root@base1 ~]# echo $A
1
# 重新打开一个shell
[root@base1 ~]# echo $A # 输出为空
(2)用户级变量写在用户的骨文件中,只针对当前用户有效
[root@base1 ~]# vim /root/.bash_profile
export A=1
[root@base1 ~]# source /root/.bash_profile # 刷新文件内容
[root@base1 ~]# echo $A
1
# 重新打开一个shell,发现A的值依然存在
[root@base1 ~]# echo $A
1
[root@base1 ~]# su - student # 但是切换到其他用户,查看不到
Last login: Sat Oct 27 22:39:56 CST 2018 on :0
[student@base1 ~]$ echo $A
(3)系统级变量被写在系统的配置文件/etc/profile中,即变量在程序运行时,保存在内存中。
[root@base1 ~]# vim /etc/profile
export A=1
[root@base1 ~]# source /etc/profile
[root@base1 ~]# echo $A
1
# 重新打开一个shell,发现A的值可以查看到,切换到其他用户,依然可以查看到
[root@base1 ~]# echo $A
1
[root@base1 ~]# su - student
Last login: Sat Dec 22 22:23:06 CST 2018 on pts/2
[student@base1 ~]$ echo $A
1
4.变量名称的规范:
变量名称中通常包含大小写字母,数字,下划线(不是必须)
例如:
WESTOS_LINUX
Westos_Linux
westoS_Linux
[root@base1 mnt]# cat /etc/shells # 查看系统中所有的shell
二、变量的设定
1.定义变量
(1)普通变量
1)普通变量赋值
变量名=value
变量名='value'
变量名="value"
2)命令结果作为内容赋值
变量名=`命令`
b=`ls`或 b=$(ls)
(2)特殊变量
$0 # 获取脚本名,如果执行时包含路经,则输出脚本路径
$n(n>0) # 脚本后跟的第n个字符
$# # 脚本后所跟的字符串的个数
$? # 检测上一条命令是否执行成功,0表示执行成功,非0表示执行失败
$$ # 获取当前shell的进程号
$* # 脚本后的所有字符串,模式为“1 2 3”
$@ # 脚本后的第一串字符串,模式为“1”“2”“3”
[root@base1 mnt]# vim test.sh
1 #!/bin/bash
2 echo \$0 is $0
3 echo \$1 is $1
4 echo \$2 is $2
5 echo \$3 is $3
6 echo \$# is $#
7 echo \$* is $*
8 echo \$@ is $@
[root@base1 mnt]# sh test.sh
$0 is test.sh
$1 is
$2 is
$3 is
$# is 0
$* is
$@ is
[root@base1 mnt]# sh test.sh redhat
$0 is test.sh
$1 is redhat
$2 is
$3 is
$# is 1
$* is redhat
$@ is redhat
[root@base1 mnt]# sh test.sh redhat westos
$0 is test.sh
$1 is redhat
$2 is westos
$3 is
$# is 2
$* is redhat westos
$@ is redhat westos
[root@base1 mnt]# vim for.sh # 编写脚本测试$*和$@的区别
10 #!/bin/bash
11 for name in "$*"
12 do
13 echo $name
14 done
[root@base1 mnt]# sh -x for.sh westos linux redhat # 只检测到一串字符
+ for name in '"$*"'
+ echo westos linux redhat
westos linux redhat
[root@base1 mnt]# vim for.sh
10 #!/bin/bash
11 for name in "$@"
12 do
13 echo $name
14 done
[root@base1 mnt]# sh -x for.sh westos linux redhat # 检测到三串字符
练习 :把日志打包成当天日期
[root@base1 mnt]# vim test.sh
1 #!/bin/bash
2 tar zcf log_$1.tar.gz /var/log
[root@base1 mnt]# sh test.sh `date +%Y-%m-%d`
[root@base1 mnt]# ls
log_2018-12-23.tar.gz
(3)read (接收用户输入)
-t 等待5秒,自动退出,
-s表示加密
-p表示提示
[root@base1 mnt]# vim test.sh
1 #!/bin/bash
2 read WESTOS
3 echo $WESTOS
[root@base1 mnt]# sh test.sh
westos # 这一行需要自己手动输入
westos # 这一行是系统读出来的
[root@base1 mnt]# vim test.sh
1 #!/bin/bash
2 read -p "please input a file name: " WESTOS
3 echo $WESTOS
[root@base1 mnt]# sh test.sh
please input a file name: lala
lala
练习:输入一个ip,测试这个ip的是否可达
[root@base1 mnt]# vim find.sh
10 #!/bin/base
11 read -p "please give me a ip: " IP
12 ping -c1 -w1 $IP &> /dev/null && echo $IP is up || echo $IP is down、
[root@base1 mnt]# sh find.sh
please give me a ip: 172.25.254.78
172.25.254.78 is up
[root@base1 mnt]# vim find.sh # 对输入的IP进行加密
10 #!/bin/bash
11 read -p "please give me a ip: " -s IP
12 ping -c1 -w1 $IP &> /dev/null && echo $IP is up || echo $IP is down
[root@base1 mnt]# sh find.sh # 输入ip时不显示
please give me a ip: 172.25.254.78 is up
2.字符的转译及变量的声明:
a=1;
$a # 表示变量,$表示取值
`` # 表示先执行该命令
\ # 表示转义单个字符,\$a 此处的$只表示字符$
‘ ’ # 强引用,批量转译' '中出现的所有字符
“ ” # 弱引用,不能转义!,$,\,`,即该变量扩展和命令扩展在" "内仍是起作用的
${} # 变量声明
$[] # 运算,把shell中可变长字符转化为整型,以用来节省资源
[root@base1 ~]# a=hello\ world # 转译空格
[root@base1 ~]# echo $a
hello world
[root@base1 ~]# a="hello world" #
[root@base1 ~]# echo $a
hello world
[root@base1 ~]# a=1
[root@base1 ~]# echo $a b # 输出变量a的值,以及一个空格和字符b
1 b
[root@base1 ~]# echo $ab # 什么都不会输出,因为系统不识别ab是什么
[root@base1 ~]# echo ${a}b # 声明a是一个变量,此时就能输出a的结果
1b
[root@base1 ~]# echo $[1+1] # 输出1+1的结果
2
[root@base1 ~]# a=(1 2 3) # 定义a数组
[root@base1 ~]# echo ${a[0]} # 调用下标依次显示,下标从0开始
1
[root@base1 ~]# echo ${a[1]}
2
[root@base1 ~]# echo ${a[2]}
3
三.计算变量的值
1.关于运算符
运算符号 | 意义 |
---|---|
+,- | 加法,减法 |
*,/,% | / 乘,除,取余 |
** | 幂运算 |
++,-- | 自增加,自减少 |
<, <=, >, >= | 比较符号 |
=, +=, -=, *=, /=, %= | 赋值运算 |
shell中常用的运算命令
运算操作与运算命令 | 含义 |
---|---|
(( )) | 用于整数运算 |
let | 用于整数运算,与(())类似 |
expr | 用于整数运算,功能相对较多 |
bc | linux下的计算器,适合小数及整数运算 |
$[ ] | 用于整数运算 |
(1)expr命令
[root@base1 mnt]# a=12
[root@base1 mnt]# expr $a + 10
22
[root@base1 mnt]# expr $a - 10
2
[root@base1 mnt]# expr $a * 10
expr: syntax error
[root@base1 mnt]# expr $a \* 10
120
[root@base1 mnt]# expr $a / 10
1
[root@base1 mnt]# expr $a % 10
2
(2)$[]和(()) 表达式
[root@base1 mnt]# a=10
[root@base1 mnt]# echo $[a+10]
20
[root@base1 mnt]# echo $[a-10]
0
[root@base1 mnt]# echo $[a*10]
100
[root@base1 mnt]# echo $[a/10]
1
[root@base1 mnt]# echo $[a%10]
0
[root@base1 mnt]# echo $((a+10))
20
[root@base1 mnt]# echo $((a-10))
0
[root@base1 mnt]# echo $((a*10))
100
[root@base1 mnt]# echo $((a/10))
1
[root@base1 mnt]# echo $((a%10))
0
(3)let命令(let命令在执行后会保存新的值)
[root@base1 mnt]# a=10
[root@base1 mnt]# let a+=10
[root@base1 mnt]# echo $a
20
[root@base1 mnt]# let a-=10
[root@base1 mnt]# echo $a
10
[root@base1 mnt]# let a*=10
[root@base1 mnt]# echo $a
100
[root@base1 mnt]# let a/=10
[root@base1 mnt]# echo $a
10
[root@base1 mnt]# let a%=10
[root@base1 mnt]# echo $a
0
练习:写一个加减乘除取余的计算器
[root@base1 mnt]# vim calculate.sh
1 #!/bin/bash
2 echo "$1+$2="$[$!+$2]
3 echo "$1-$2="$[$1-$2]
4 echo "$1*$2="$[$1*$2]
5 echo "$1/$2="$[$1/$2]
6 echo "$1%$2="$[$1%$2]
[root@base1 mnt]# sh calculate.sh 2 3
2+3=3
2-3=-1
2*3=6
2/3=0
2%3=2