shell脚本——变量,变量的运算

一、概念

1、变量的定义:

变量即在程序运行过程中它的值是允许改变的量,
变量是用一串固定的字符来标志不固定的值的一种方法,
变量是一种使用方便的占位符,用于引用计算机内存地址,该地址可以存scripts运行时可更改的程序信息。
在shell中变量是不可能永久保存在系统中的,必须在文件中声明。

2.在shell脚本中变量的分类:

在shell中变量分为环境级变量,用户级变量,系统级变量
(1)环境级变量
环境级变量也可叫全局变量,只在当前shell中生效,shell关闭变量丢失,可以在创建他们的shell及派生出的子shell中使用(无需定义,直接可以使用,如:$UID)
相关命令:

set :输出所有变量
env:只显示全局变量
declare:输出所有变量,函数,整数等

测试:

[root@server ~]# export A=1
[root@server ~]# echo $A
1

# 重新打开一个shell
[root@server ~]# echo $A  # 输出为空

(2)用户级变量
用户级变量写在用户的骨文件中,只针对当前用户有效

[root@server ~]# vim /root/.bash_profile 
export A=1
[root@server ~]# source /root/.bash_profile  # 刷新文件内容
[root@server ~]# echo $A
1

# 重新打开一个shell,发现A的值依然存在
[root@server ~]# echo $A
1 
[root@server ~]# su - student    # 但是切换到其他用户,查看不到
Last login: Sat Oct 27 21:25:17 CST 2018 on :0
[student@server ~]$ echo $A

(3)系统级变量
系统级变量被写在系统的配置文件/etc/profile中,即变量在程序运行时,保存在内存中。

[root@server ~]# vim /etc/profile
export A=1
[root@server ~]# source /etc/profile
[root@server ~]# echo $A
1

# 重新打开一个shell,发现A的值可以查看到,切换到其他用户,依然可以查看到

[root@server ~]# echo $A
1
[root@server ~]# su - student
Last login: Sat Dec 22 22:23:06 CST 2018 on pts/2
[student@server ~]$ echo $A
1

3、变量名称的规范:

变量名称中通常包含大小写字母,数字,下划线(不是必须)
例如:

WESTOS_LINUX
Westos_Linux
westoS_Linux

[root@server ~]# cat /etc/shells # 查看系统中所有的shell
在这里插入图片描述

二、变量的设定

1.定义变量

(1)普通变量
普通变量赋值

变量名=value
变量名='value'
变量名="value"

注意:建议没有特别要求时,字符串都加双引号,需要原样输出就加单引号

[root@server ~]# a=hello
[root@server ~]# echo $a
hello
[root@server ~]# b='hello'
[root@server ~]# echo $b
hello
[root@server ~]# c="hello"
[root@server ~]# echo $c
hello
[root@server ~]# a=westos-$a
[root@server ~]# echo $a
westos-hello
[root@server ~]# b='westos-$a'         ##不转译变量,按原样输出
[root@server ~]# echo $b
westos-$a
[root@server ~]# c="westos-$a"         ##转移变量
[root@server ~]# echo $c
westos-westos-hello
[root@server ~]# a=westos hello        ##定义变量有空格时,要加“”
bash: hello: command not found...
[root@server ~]# a="westos hello"
[root@server ~]# echo $a
westos hello

命令结果作为内容赋值

变量名=命令
b=ls或 b=$(ls)

测试:

[root@server mnt]# CMD=`ls -l`
[root@server mnt]# echo $CMD
total 8 -rwxr-xr-x. 1 root root 492 Dec 22 10:25 test.sh -rwxr-xr-x. 1 root root 40 Dec 22 10:40 westos.sh

[root@server mnt]# CMD=$(ls -l)
[root@server mnt]# echo $CMD
total 8 -rwxr-xr-x. 1 root root 492 Dec 22 10:25 test.sh -rwxr-xr-x. 1 root root 40 Dec 22 10:40 westos.sh

(2)特殊变量

$0         # 获取脚本名,如果执行时包含路经,则输出脚本路径
$n(n>0)    # 脚本后跟的第n个字符
$#         # 脚本后所跟的字符串的个数
$?         # 检测上一条命令是否执行成功,0表示执行成功,非0表示执行失败
$$         # 获取当前shell的进程号
$*         # 脚本后的所有字符串,模式为“1 2 3”
$@         # 脚本后的第一串字符串,模式为“1”“2”“3”

$0

[root@server mnt]# cat westos.sh 
#!/bin/bash
echo $0
[root@server mnt]# sh westos.sh 
westos.sh
[root@server mnt]# /mnt/westos.sh 
/mnt/westos.sh

$n

[root@server mnt]# cat westos.sh 
#!/bin/bash
echo $1 $2
[root@server mnt]# sh westos.sh hello westos
hello westos
[root@server mnt]# sh westos.sh hello redhat
hello redhat

[root@server mnt]# echo \${1..10} > westos.sh 
[root@server mnt]# cat westos.sh 
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10
[root@server mnt]# sh westos.sh  {a..z}
a b c d e f g h i a0
[root@server mnt]# cat westos.sh 
$1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}
[root@server mnt]# sh westos.sh  {a..z}
a b c d e f g h i j

$#

[root@server mnt]# cat westos.sh 
echo $#
[root@server mnt]# sh westos.sh {1..100}
100

$?

[root@server mnt]# ls /etc/passwd
/etc/passwd
[root@server mnt]# echo $?
0
[root@server mnt]# ls /etc/password
ls: cannot access /etc/password: No such file or directory
[root@server mnt]# echo $?
2

$$

[root@server mnt]# echo $$
2795
[root@server mnt]# ps
  PID TTY          TIME CMD
 2795 pts/2    00:00:00 bash
 4277 pts/2    00:00:00 ps

测试: $*和$@的区别

$*

[root@server mnt]# vim for.sh  
 10 #!/bin/bash
 11 for name in "$*"
 12 do
 13         echo $name
 14 done
[root@server mnt]#  sh -x for.sh westos linux redhat  # 只检测到一串字符
+ for name in '"$*"'
+ echo westos linux redhat
westos linux redhat

$@

[root@server mnt]# vim for.sh 
 10 #!/bin/bash
 11 for name in "$@"
 12 do
 13         echo $name
 14 done
[root@server mnt]#  sh -x for.sh westos linux redhat  # 只检测到三串字符
+ for name in '"$*"'
+ echo westos linux redhat
westos
+ for name in '"$*"'
+ echo westos linux redhat
westos linux redhat
linux
+ for name in '"$*"'
+ echo westos linux redhat
redhat

练习 :把日志打包成当天日期

[root@server mnt]# vim test.sh 
  1 #!/bin/bash
  2 tar zcf log_$1.tar.gz /var/log
[root@server mnt]# sh test.sh  `date +%Y-%m-%d`
[root@server mnt]# ls
log_2018-12-23.tar.gz 

(3)read (接收用户输入)

-t 等待时间后,自动退出,
-s表示加密
-p表示提示

测试:

[root@server mnt]# vim test.sh
  1 #!/bin/bash
  2 read WESTOS
  3 echo $WESTOS
[root@server mnt]# sh test.sh 
westos             # 这一行需要自己手动输入
westos             # 这一行是系统读出来的
[root@server mnt]# vim test.sh 
  1 #!/bin/bash
  2 read -p "please input a file name: " WESTOS   #  WESTOS表示: 用变量WESTOS接受输入的内容
  3 echo $WESTOS      # $WESTOS表示:输出接受的内容

测试:

[root@server mnt]# sh test.sh 
please input a file name: hello  手动输入hello
hello  # 这是系统接受的

练习:输入一个ip,测试这个ip的是否可达

[root@server 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@server mnt]# sh find.sh 
please give me a ip: 172.25.254.61
172.25.254.78 is up
[root@server mnt]# vim find.sh  # 对输入的IP进行加密
 10 #!/bin/base
 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@server mnt]# sh find.sh    # 输入ip时不显示
please give me a ip: 172.25.254.61 is up

2、字符的转译及变量的声明:

a=1;  
$a          #  表示变量,$表示取值
``          #  表示先执行该命令
\           #  表示转义单个字符,\$a 此处的$只表示字符$
‘ ’         #  强引用,批量转译' '中出现的所有字符
“ ”         #  弱引用,不能转义!,$,\,`,即该变量扩展和命令扩展在" "内仍是起作用的
${}         #  变量声明
$[]         #  运算,把shell中可变长字符转化为整型,以用来节省资源

测试:

[root@server ~]# a=hello\ world   # 转译空格
[root@server ~]# echo $a  
hello world
[root@server ~]# a="hello world"  # 
[root@server ~]# echo $a
hello world
[root@server ~]# a=1
[root@server ~]# echo $a  b  # 输出变量a的值,以及一个空格和字符b
1 b
[root@server ~]# echo $ab  # 什么都不会输出,因为系统不识别ab是什么

[root@server ~]# echo ${a}b  # 声明a是一个变量,此时就能输出a的结果
1b
[root@server ~]# echo $[1+1]   # 输出1+1的结果
2
[root@server ~]#  a=(1 2 3)     # 定义a数组
[root@server ~]#  echo ${a[0]}   # 调用下标依次显示,下标从0开始
1
[root@server ~]# echo ${a[1]}
2
[root@server ~]# echo ${a[2]}
3

三.计算变量的值

关于运算符
运算符号含义
+,-加法,减法
*,/,%乘,除,取余
**幂运算
++,–自增加,自减少
<, <=, >, >=比较符号
=, +=, -=, *=, /=, %=赋值运算
shell中常用的运算命令
运算操作与运算命令含义
(( ))用于整数运算
let用于整数运算,与(())类似
expr用于整数运算,功能相对较多
bclinux下的计算器,适合小数及整数运算
$[ ]用于整数运算
1、expr命令
[root@server mnt]# a=123
[root@server mnt]# expr $a + 10   #注意:三个字符要用空格隔开
133
[root@server mnt]# expr $a - 10
113
[root@server mnt]# expr $a * 10   #此命令不能识别*,必须加\,\表示转译
expr: syntax error
[root@server mnt]# expr $a \* 10
1230
[root@server mnt]# expr $a / 10
12
[root@server mnt]# expr $a % 10
3
2、$[]和(()) 表达式
[root@server mnt]# echo $[a+10]
20
[root@server mnt]# echo $[a-10]
0
[root@server mnt]# echo $[a*10]    #这里乘号不需要转译
100
[root@server mnt]# echo $[a/10]
1
[root@server mnt]# echo $[a%10]
0
[root@server mnt]# echo $((a+10))
20
[root@server mnt]# echo $((a-10))
0
3、let命令(let命令在执行后会保存新的值)
[root@server mnt]# a=10
[root@server mnt]# let a+=10
[root@server mnt]# echo $a     # 查看a的值,发现ade值已经改变
20
[root@server mnt]# let a-=10
[root@server mnt]# echo $a
10
[root@server mnt]# let a*=10
[root@server mnt]# echo $a
100
[root@server mnt]# let a/=10
[root@server mnt]# echo $a
10
[root@server mnt]# let a%=10
[root@server mnt]# echo $a
0
4、小数运算工具bc
[root@server mnt]# echo "scale=4;1.23*4.56" | bc   (scale=4,表示保留4位小数)
5.6088
[root@server mnt]# echo "scale=2;1.23*4.56" | bc
5.60
[root@server mnt]# echo 2.2+5.4 | bc
7.6
[root@server mnt]# echo 3.47+1.12 | bc
4.59
练习(计算两个数的加减乘除)
[root@server mnt]# vim jisuan.sh
#!/bin/bash
echo "$1+$2=$[$1+$2]"
echo "$1-$2=$[$1-$2]"
echo "$1*$2=$[$1*$2]"
echo "$1/$2=$[$1/$2]"
echo "$1**$2=$[$1**$2]"
echo "$1%$2=$[$1%$2]"

[root@server mnt]# sh jisuan.sh  2 3
2+3=5
2-3=-1
2*3=6
2/3=0
2**3=8
2%3=2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值