shell编程入门--变量和变量的数值计算

shell概述

shell是linux的一层外壳,它包在linux内核的外面,为用户和内核之间的交互提供了一个接口;系统中的命令都是用shell去解释,当用户下达指令给操作系统的时候,实际上是把指令告诉shell,经过shell解释,处理后让内核做出相应的动作。;系统的回应和输出的信息也由shell处理,shell接收系统回应的输出并显示到屏幕中;

Shell的作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行一条,这种方式称为交互式(Interactive).
Shell还有一种执行命令的方式称为批处理(Batch),用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。

shell脚本概述

解释型语言—shell脚本、python,运行效率低,开发过程较为简单,基本只适用企业内部。

编译型语言—C语言、java,执行效率高。具有创造性,需要开发软件去编译,编译是一个将描述性语言翻译成机器可以读懂的语言过程。

Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。

  • 简单的说,当命令或者程序不在命令行执行,而是通过一个程序文件来执行,这个程序就被称为shell脚本
  • 也就是在shell脚本里内置了多条命令,语句,循环控制,然后将这些命令一次性执行完毕,这种通过文件执行命令的方式称为非交互式

为什么使用shell脚本
•1. 适合处理操作系统底层的业务,有众多系统命令为其做支撑(还有文本处理三兄弟grep,sed,awk)
•2. 适合处理纯文本文件,linux中许多服务配置文件,启动脚本,都是纯文本(httpd,nfs,mysql,nginx,lvs)
•3. linux系统脚本用shell开发更简单

shell脚本的建立

脚本(一般以.sh结尾):

第一行:#!/bin/bash     指定解释器:由哪个程序来执行脚本内容
#!:幻数
注意:#!/bin/bash必须写在第一行,否则会被认为是注释

脚本开发的规范:

1.注释:可以命令后,也可以自成一行
2.脚本信息:
#!/bin/bash
#Date:2018-12-14
#Author:westos-wsp
#Connect:[email protected]
#Desc:This script is for...
#Version:1.0
3.脚本名:最好以.sh结尾

练习:编写规范化脚本实现清空日志

扫描二维码关注公众号,回复: 5242951 查看本文章

[root@pxe-server script]# vim cleanlog.sh
[root@pxe-server script]# sh cleanlog.sh
Logs cleaned up...

脚本的执行过程

1.先加载系统环境变量
查看系统环境变量的命令:env


2.一条一条命令执行,遇到子脚本,先执行子脚本,然后返回父脚本继续执行

脚本的调用

建立脚本(一般以.sh结尾):

[root@pxe-server script]# vim test.sh

#!/bin/bash
echo "Hello World"

方法一:脚本无执行权限,用sh调用(或者bash)

[root@pxe-server script]# sh test.sh
Hello World
[root@pxe-server script]# bash test.sh
Hello World

方法二:脚本有执行权限,用绝对路径调用或者在当前目录下用./调用

[root@pxe-server script]# chmod +x test.sh

[root@pxe-server script]# /root/script/test.sh
Hello World
[root@pxe-server script]# ./test.sh
Hello World

方法三:使用source命令或“.”(点命令)来调用指定shell文件

该调用方式与以上两种方式的区别:前面两种脚本执行方式会重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。

用source命令和“.”(点命令)是Shell的内建命令,这种方式不会创建子Shell,而是直接在交互式Shell下逐行 执行脚本中的命令。这两个命令都以一个脚本为参数,该脚本在当前shell的环境执行,即不会启动一个新的子进程。所有在脚本中设置的变量将成为当前Shell的一部分。

运行一个含有新建变量的脚本体现该区别:

[root@pxe-server script]# vim test.sh
#!/bin/bash
a=2

[root@pxe-server script]# sh test.sh
[root@pxe-server script]# echo $a

[root@pxe-server script]# source test.sh
[root@pxe-server script]# echo $a
2

shell脚本中变量的定义

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

测试脚本:

[root@server script]# vim char.sh

#!/bin/bash
i=westos
a=hello-$i
b="hello-$i"      ##双引号解析变量
c='hello-$i'       ##单引号不解析变量
echo $a
echo $b
echo $c

[root@server script]# sh char.sh
hello-westos
hello-westos
hello-$i

shell脚本中的特殊变量

$0:获取脚本文件名,用绝对路径执行脚本文件,则输出脚本路径
$n(>0):执行脚本时的第n个参数
$#:执行脚本时输入参数的个数
$*:
$@:

$?:表示上条命令执行结果的返回值,0表示执行成功,非0表示执行失败

特殊变量的脚本测试:

$0:获取脚本文件名

[root@server script]# vim test1.sh

#!/bin/bash
echo $0

[root@server script]# sh test1.sh
test1.sh                    ##脚本的文件名

[root@server script]# /root/script/test1.sh
/root/script/test1.sh                    ##脚本的绝对路径

$n(>0):执行脚本时的第n个参数

[root@server script]# vim test1.sh

#!/bin/bash
echo $1 $2 $3

[root@server script]# sh test1.sh a b c
a b c  

注意,当n是多位数时,需要加上{}

[root@server script]# vim test1.sh

#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10}

[root@server script]# sh test1.sh {a..z}
a b c d e f g h i j

${ } 用来作变量替换。
一般情况下,$var 与 ${var} 并没有啥不一样。
但是用 ${ } 会比较精确的界定变量名称的范围,

例子:原本是打算先将 $A 的结果替换出来,然后再补一个 B 字母于其后,但在命令行上,真正的结果却是只会将变量名称为 AB 的值输出来

[root@server ~]# A=5

[root@server ~]# AB=3

[root@server ~]# echo $AB                 ##$AB将变量名称为 AB 的值输出来
3

[root@server ~]# echo ${A}B               ##${A}B先将 $A 的结果替换出来,然后再补一个 B 字母于其后
5B
 

$#:执行脚本时输入参数的个数

[root@server script]# vim test1.sh

#!/bin/bash
echo $#

[root@server script]# sh test1.sh {a..z}
26

$?:表示上条命令执行结果的返回值,范围为[0-255].当$0=0,时表示命令执行没有错误输出,,非0表示执行失败

[root@server script]# ls
char.sh  cleanlog.sh  test1.sh  test.sh
[root@server script]# echo $?
0
[root@server script]# rr
bash: rr: command not found...
[root@server script]# echo $?
127

$$:表示脚本运行的进程ID

将命令的结果赋值给变量:

在 bash shell 中,$( ) 与 ` ` (反引号) 都是用来做命令替换用(command substitution)的。

<1>使用` ` 命令

[root@server script]# a=`ls -l`
[root@server script]# echo $a
total 16 -rw-r--r--. 1 root root 82 Dec 24 02:56 char.sh -rw-r--r--. 1 root root 504 Dec 24 01:38 cleanlog.sh -rwxr-xr-x. 1 root root 50 Dec 24 04:04 test1.sh -rwxr-xr-x. 1 root root 16 Dec 24 01:04 test.sh

<2>使用$( ) 命令

[root@server script]# b=$(ls -l)
[root@server script]# echo $b
total 16 -rw-r--r--. 1 root root 82 Dec 24 02:56 char.sh -rw-r--r--. 1 root root 504 Dec 24 01:38 cleanlog.sh -rwxr-xr-x. 1 root root 50 Dec 24 04:04 test1.sh -rwxr-xr-x. 1 root root 16 Dec 24 01:04 test.sh

练习:打包日志,并将名字命名为log_xxxx-xx-xx.tar.gz,xxxx-xx-xx为当天的日期

将日期显示为xxxx-xx-xx形式的三种命令:

(1)date -I

(2)date +%F

(3)date +%Y-%m-%d

打包日志:

[root@server script]# tar zcf log_$(date -I).tar.gz /var/log

变量的数值计算

1)expr命令(只支持整数运算)

'expr'支持普通的算术操作,算术表达式优先级低于字符串表达式,高于逻辑关系表达式。
'+ -'
     加减运算。两端参数会转换为整数,如果转换失败则报错。
 
'* / %'
     乘,除,取余运算。两端参数会转换为整数,如果转换失败则报错。

[root@server script]# a=123

[root@server script]# expr $a + 10
133
[root@server script]# expr $a - 10
113
[root@server script]# expr $a \* 10     ##expr命令进行乘法计算时需要在乘法符号前加上转义符
1230
[root@server script]# expr $a % 10
3
[root@server script]# expr $a / 10
12
[root@server script]# echo $a     ##expr命令进行变量计算时不会改变变量的值
123

任意操作符两端都需要有空格,否则:

2)$[ ]$(( ))表达式(只支持整数运算)

在 $(( )) 中的变量名称,可于其前面加 $ 符号来替换,也可以不用。

$[ ] $(( )) :

它们是一样的,都是进行数学运算的。支持+ - * / %:分别为 “加、减、乘、除、取模”。但是注意,bash只能作整数运算,对于浮点数是当作字符串处理的。

[root@server script]# a=100
[root@server script]# echo $[a+10]
110
[root@server script]# echo $[a-10]
90
[root@server script]# echo $[a*10]
1000
[root@server script]# echo $[a/10]
10
[root@server script]# echo $[a%10]
0
[root@server script]# echo $((a%10))
0
[root@server script]# echo $((a+10))
110
[root@server script]# echo $a                      ##$(( ))命令与$[  ]命令进行变量计算时不会改变变量的值
100

3)let 命令(只支持整数运算)

let 命令是 BASH 中用于计算的工具,提供常用运算符还提供了方幂“**”运算符,用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符,则必须引起来。

格式:let arg1 [arg2 ......]

与expr命令相比,let命令更简洁直观

 [ ]表示可以有多个参数,arg n (n=1,2…)

 运算符与操作数据之间不必用空格分开,但表达式与表达式之间必须要用空格分开

当运算符中有<、>、&、|等符号时,同样需要用引号(单引号、双引号)或者斜杠来修饰运算符

 [root@server script]# let a=0
[root@server script]# echo $a
0
[root@server script]# let a=4+4
[root@server script]# echo $a
8
[root@server script]# let a+=10
[root@server script]# echo $a
18

[root@server script]# let b=a**2 a+=10            ##执行多个表达式,表达式与表达式之间必须要用空格分开
[root@server script]# echo $b $a
324 28

4)小数运算工具bc

[root@server script]# echo 1.23+3.45 | bc
4.68
[root@server script]# echo "scale=4;1.23*4.46" | bc
5.4858
[root@server script]# echo "scale=2;1.23*4.46" | bc
5.48

练习:

<1>编写一个脚本,实现输入两个整数,输出这两个整数的加减乘除及结果

[root@server script]# vim jisuan.sh

#!/bin/bash
read -t 5 -p "请输入两个整数:" a b
echo "a+b=$[a+b]"
echo "a-b=$[a-b]"
echo "a*b=$[a*b]"
echo "a/b=$[a/b]"
echo "a%b=$[a%b]"
echo "a**b=$[a**b]"

执行该脚本:

<2>编写一个脚本,实现输入两个小数,输出这两个整数的加减乘除及结果

[root@server script]# vim jisuan1.sh

#!/bin/bash
read -t 5 -p "请输入两个数:" a b
echo "a+b=`echo "scale=2;$a+$b" | bc`"
echo "a-b=`echo "scale=2;$a-$b" | bc`"
echo "a*b=`echo "scale=2;$a*$b" | bc`"
echo "a/b=`echo "scale=2;$a/$b" | bc`"
echo "a%b=`echo "scale=2;$a%$b" | bc`"

执行该脚本:

由以上脚本的执行结果可以看出,计算结果的整数位是0时,只显示小数点以及后面的小数位,这种现象可以通过以下语句解决:

echo "a/b=$(printf "%.2f" `echo "scale=2;$a/$b" | bc`)"

猜你喜欢

转载自blog.csdn.net/weixin_40172997/article/details/85231753