shell编程入门--变量和变量的数值计算
日期: 2018-12-26 分类: 个人收藏 375次阅读
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:wsp439@sina.com
#Desc:This script is for...
#Version:1.0
3.脚本名:最好以.sh结尾
练习:编写规范化脚本实现清空日志
[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`)"
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
精华推荐