一、 什么是变量
变量源于数学,在计算机语言中能储存计算机结果或能表示值的抽象概念,变量可以由变量名访问,在指令语言中,变量通常是可变的。Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。
1. 变量的命令规则
1) 不能使程序中的保留字:例如if, for;
2) 只能使用数字、字母及下划线,且不能以数字开头
3) 见名知义
4) 统一命名规则:驼峰命名法
2. 变量分类(根据生效范围划分)
本地变量,环境变量,局部变量,位置变量,特殊变量
3. 变量类型
字符
数值:整型、浮点型
a) 强类型:定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误。
b) 弱类型:无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用
只读变量:只能声明,不能修改和删除
readonly name
declare –r name
4. 算数运算
+, -, *, /, %取模(取余), **(乘方)
实现算术运算:
(1) let var=算术表达式
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3 …)
(5) declare –i var = 数值
(6) echo ‘算术表达式’ | bc
乘法符号有些场景中需要转义,如*
5. 增强型赋值:
+=, -=, *=, /=, %=
例如:letsum+=3
自加3后自赋值
自增,自减:
let var+=1
let var++
let var-=1
let var–
二、 本地变量
对当前shell进程有效,出当前shell进程之外的其他进程无效,比如我设定一个本地变量a=1,这个值只在当前用户当前shell有生命周期意义,如果在shell中又开启一个子shell或退出shell重新登录一个shell,那么这个a的变量值就无效了,这个方法的有点就是用户不能对其他shell或进程设置次变量有效。
使用变量时,如果用“{}”括起来,可以防止shell误解为变量值,尽管不必一定这样做,但这确实可用,设定本地变量的格式如下:
name=’value’
name=”root’ 直接使用字符串
name=”$USER 变量引用,将引用$USER这个变量的值作为name的变量值
name=`command`,name=$(command),比如我使用name=`id -un`,取出id这个命令的执行结果来作为name变量的值
变量引用又分为强引用和弱引用,当变量时强引用(单引号)时,其中的变量引用不会被替换为变量值,弱引用(双引号)时,其中的变量引用会被替换为变量值,就拿杠杆name=$USER来说,如果我加的是双引号,那么$USER这个变量就会将值赋值给name这个变量,如果是单引号,值将会原样输出
显示已定义的所有变量:set
删除变量:unset 变量名,当我们执行某个程序完成后,最好将变量的删除,以释放内存空间。
三、 环境变量
对当前shell以及子shell都有效,登录进程称为父进程,shell中执行的用户称为子进程,不像本地变量只用于当前shell,,他能用于所有的子进程,/etc/profile文件中已经设置了一些环境变量。将之放入profile文件意味着每次登录式这些值都将被初始化。所有的环境变量均为大写。环境变量应用于用户进程前,必须使用export命令导出,环境变量与本地变量设置方法相同
export name=’value’
declclare –x name=value
变量引用:$name, ${name}
显示已定义的环境变量printenv ,env,export命令查看
清楚环境变量:unset 环境变量名称
bash有许多内建的环境变量:PATH, SHELL, USRE,UID, HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1
四、 局部变量
对当前shell进程中的某段代码有效,在程序运行期间不是一直存在,而只是在函数执行期间存在,函数的一次调用结束后,变量就会撤销,其所占的内存也会被收回,比如我在脚本里定义个局部变量,当我执行完脚本之后这个局部变量就会被删除。
五、 位置变量
$1,$2…来表示,用于让脚本在执行的过程中调用,通过命令行传递参数
六、 特殊变量
$?:上个命令的执行状态结果,$?返回0。可以在任何命令或脚本中返回此变量以获得返回信息。基于此信息,可以在脚本中做更进一步的研究,返回0意味着成功,非0为出现错误。
$0:指脚本名本身
$#:传递给脚本参数的个数
$*:以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过9个。
$@:与$ #相同,但是使用时加引号,并在引号中返回每个参数,两者不加引号表示的意思相同,如果加引号,前者表示的是一个整体,当做一个参数来使用,而后者为多个参数。
$-:显示shell使用的当前选项,与set命令功能相同
$!:后台运行的最后一个进程的进程id号
七、 三者之间的差异
本地变量,环境变量,局部变量之间的区别,三者的影响范围不同,范围从大到小依次是,环境变量,本地变量,局部变量,而环境也是全局的,对所有用户都生效,其他两个,只针对当前用户有效。
环境变量,传递给子进程的变量,遗传性是环境变量和其他两者之间的差别,只能单向从父进程传递给子进程,不管子进程的环境变量如何变化,都不会影响父进程的环境变量
作业
1、 编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。
显示主机信息用hostname命令可以实现
ipv4的地址需要配合cut ,grup等文本处理工具
操作系统版本可以查看/etc/centos-release 的文件内容便可查到
内核版本使用uname –r 命令来查询
cpu,使用lscpu,查询到一大串讯息,截图cpu型号即可
内存大小,可以使用命令free 也可以查看/pro/meminfo文件的内容,来查看内存的大小
硬盘的容量可以使用lsblk列出块设备的信息,也可是用fdisk –l命令来列出硬盘的容量,通过文本工具来截取所需的内容
具体脚本内容如下:
#!/bin/bash
#
Hname=`hostname`
echo "the host name is $Hname"
IP=` ifconfig |grep "inet addr"|cut -d : -f2|cut -d ' ' -f1|head -1`
echo "the ip address is $IP "
Osversion=`cat /etc/centos-release`
echo "the oprating system version is $Osversion"
Kversion=`uname -r`
echo "the kernel version is $Kversion"
Cpu=`cat /proc/cpuinfo |grep ‘model name’ -n |cut -d : -f3|head -1 `
echo -e "the cpu type is $Cpu"
Mem=`cat /proc/meminfo |head -1 |cut -d : -f2`
echo "the memory total is $Mem"
Disk=`fdisk -l|grep "^Disk /dev/sd[a-z]" |cut -d : -f2|cut -d , -f1 `
echo "the disk total is $Disk"
2、 编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中
将/etc/下所有文件和目录都备份到/root/下以日期命令的文件中,利用cp命令时需要带上-r递归选项,连同目录一起复制,日滴只需要在脚本中利用命令替换即可
#!/bin/bash
cp -r /etc/ /root/`date +%F%T`
ls /root/`date +%F%T`
3、 编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
利用df -h 命令查看硬盘分区中空间利用率最大的值,其中要出去光盘的使用率,配合使用文本处理工具来找出空间利用率最大值
#!/bin/bash
#
use=`df -P|grep -v "/dev/sr0"|tr -s ' ' ':'|cut -d : -f5|sort -nr|head -1`
echo “ The disk has use : $use”
4、 编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序
#!/bin/bash
#
Link=`netstat -nt|tr -s ' ' ':'|cut -d : -f4|grep -v "[[:alpha:]]"|sort -rn`
echo –e “thes host is :\n $Link
5、 写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和
利用sed截取/etc/passwd文件中的第10行和20行,利用cut
取出他们的uid保存在变量中,然后计算两者之和
#!/bin/bash
#
A=`sed -n '10p' /etc/passwd |cut -d : -f3`
B=`sed -n '20p' /etc/passwd |cut -d : -f3`
C=$[$A + $B]
echo $C
6、 写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
查找文件中的空行,并统计行数保存在一个变量中,以此来计算两个变量之和
#!/bin/bash
#
A=`grep "^$" /etc/rc.d/rc.sysinit|wc -l`
B=`grep "^$" /etc/fstab |wc -l`
#sum=$(($A+$B ))
sum=$[ $A + $B ]
echo $sum
7、 写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件
列出目录下的所有文件和目录通过wc来统计文件的个数
#!/bin/bash
#
A=`ls /etc/|wc -l`
B=`ls /var/ |wc -l`
C=`ls /usr/ |wc -l`
D=$[$A + $B +$C]
echo $D
8、 写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
#!/bin/bash
read -p "please input a filename :" FILE
[ $# -lt 1 ] && read -p "please input filename again :" FILE
sum=`grep "^$" $FILE |wc -l `
echo $sum
9、 写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”
#!/bin/bash
#
[ $# -lt 1 ] && read -p "please input a ipv4 address:" IP
echo $IP | grep -Eo "(\<([0-9]|1[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>)\.){3}(\<[0-9]|1[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>)"
[ $? -eq 0 ] && ping -c1 -w1 $IP &>/dev/null && echo "the ip is up,can be access " || exit 3
10、判断硬盘的每个分区空间和inode的利用率是否大于80,如果是,发邮件通知root磁盘满
#!/bin/bash
#
#device
ddev=`df -h |grep "sd[a-z]"|cut -d ' ' -f1`
duse=`df -P|grep -v "/dev/sr0"|grep -v "Filesystem"|tr -s ' ' ':'|cut -d : -f5|sort -nr |head -1 |cut -d % -f1`
#the inode use percent
Iuse=`df -Pi|grep -v "/dev/sr0"|grep -v "Filesystem"|tr -s ' ' ':'|cut -d : -f5|sort -nr |head -1|cut -d % -f1 `
[ "$duse" -ge 80 ] && echo "" |mail -s "the disk space is too samll" root || [ "$Iuse" -ge 30 ] && echo "the inod number is too samll" |mail -s "dsik About to run out" root ||exit 3
11、 指定文件做为参数,判断文件是否为.sh后缀,如果是,添加x权限
#!/bin/bash
#
[ $# -lt 1 ] && read -p " please input a filename :" File
[ ! -e $File -a ! -f $File ] && echo "please input a true file " && exit 3
echo $File |grep -q ".*\.sh" && chmod +x $File ; echo "the file add chmod finshed "|| echo "this i not a sh file"
12、判断输入的IP是否为合法IP
#!/bin/bash
#
read -p " please input a ip address: " IP
[ -z $IP ] && read –p please input a ip address :” IP
A=` echo $IP |grep -Eo "(\<([0-9]|1[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>)\.){3}(\<[0-9]|1[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>)"|wc -l`
[ $A -gt 0 ] && echo " the ip is legal" || echo " the ip is not legal"
13、计算1+2+3+…+100
#!/bin/bash
#
sum=`echo {1..100}|tr ' ' '+' |bc `
echo "The sum is $sum."
14、输入起始值A和最后值B,计算从A+(A+1)…+(B-1)+B的总和
#!/bin/bash
#
read -p "please input a number :" A
read -p "please input a number :" B
[ $A -ge $B ] && echo "sum is `seq -s+ $B $A |bc `" || echo "sum is `seq -s+ $A $B |bc`"
原创文章,作者:fszxxxks,如若转载,请注明出处:http://www.178linux.com/33721