变量
变量:能储存计算结果或能表示值抽象概念,其指向的内存空间中一段地址。
变量赋值:name=value
溢出:字符超过定义内存中间大小
变量类型:数据类型,存储的格式,参与的运算
编程语言:弱类型编程语言shell
变量声明:无需声明数据类型
不以数字开头,字符,数字,下划线,符号组合而成,不能使用系统保留字符(if,esle)如
apple_sum,appleSum,user_name,userN等等ame
变量赋值,用‘=’
apple_sum=10, appleSum=10,等等
user_name=xiong ,userName=xiong,等等
变量引用:$变量 或者 ${变量}
echo $apple_sum $user_name $appleSum
bash变量类型 注意:数字不加引号,其他都加双引号,在awk中正好相反,单引号表示解析,双引号表示不解析
1.本地变量:shell程序定义的变量,作用域仅限于当前进程本身,sshd终端开启的进程
[root@localhost ~]# pstree
2.环境变量:linux定义的特殊变量,作用域为当前shell进程及其子进程,如:USER,UID,SHELL,HISTSIZE,等等
环境变量在/etc/profile, /etc/profile.d , /etc/bashrc , 用户目录下.bash_profile,.bashrc等中定义
环境变量声明种类: 引用为:${变量},提醒中变量多是大写,我们在写shell尽量不要大写
1. export name=value 或者 name=value;export name
2.declare -x name=value 或者 declare -x; x=value
可以用:export,printenv,env,delclare -x查看系统环境变量,撤销环境变量用:unset 变量
3.只读变量:
declare -r 变量,readonly 变量 ,只读无法重新赋值,不支持撤销,随shell进程终止而终止。
4.命令变量,用反引号(` =shift+波浪号)
1种:name=`echo xiong` 2种:name=$(echo xiong)
5.局部变量:作用域仅为程序的某个片(函数上下文)
用local定义,也可不用
6.参数变量:当执行的shell进程传递的参数
7.特殊变量 shell内置的有特殊功用的变量
$0:获取当前执行shell脚本的文件名
$n:获取当前执行shell脚本的第n个参数,n=1,2,3,4…..9,当n>9时,用${10}引用
$#获取当前执行shell脚本参数总个数
$*所有参数
$@所有参数
$?获取当前shell执行状态,0表示成功,1-255表示失败,2权限不够,126不能执行,127未找到名利
$$获取当前shell执行的pid号
$!获取上个shell执行的pid号
${#变量名} 获取shell变量字符长度, 返回变量字符长度 ${#xiong}, 或用 echo $变量 | wc -m,返回变量字符长度
${变量:位置数}从位置数后截取字符串,maoxiong=maoxiong, echo ${maoxiong:2} 将显示:oxiong
${变量:位置起始a,位置结束b} 从变量第a位置,截取到b位置: ${maoxiong:2:2} echo ${maoxiong} | cut -c 3-4
${变量#删除字符串}删除变量指定字符串 ,maoxiong=l am a boy;${maoxiong#l am} 结果显示a boy
${变量##删除字符串}删除变量指定字符串 ,maoxiong=l am a boy;${maoxiong##l am a } 结果显示boy
${变量%删除字符串,从结尾处删除} maoxiong=l am a boy,${maoxiong%boy} ,结果显示l am a old
${变量/需要替换的字符/替换的字符} ${maoxiong/l am /you are},结果显示为you are boy
${变量/#需要替换的字符/替换的字符}从开头开始匹配 ${maoxiong/#l am /you are},结果显示为you are boy
变量=${man:-word}如果变量名存在,且非null,则返回变量的值。否则,返回word字符串。
用途:如果变量未定义,则返回默认值。范例:
${value:-word},如果value未定义,则表达式值为word
result=${man:-unset}如果man没值,则result值为unset。
变量=${man:=word}如果变量名存在且非null,则返回变量值。否则,设置这个变量值为word,并返回其值。
用途:如果变量未定义,则设置变量为默认值,并返回默认值。
result=${man:=set} 如果man没有值,则将unset值赋给man,在将值赋给result
变量=${man:?"not defined}如果变量名存在且非null,则返回变量的值。否则显示变量名:message,并退出当前的命令或者脚本。用途:用于捕捉由于变量未定义而导致的错误,并退出程序
result=${man:?word} 如变量man存在,则返回word,否则返回空
变量=${value:+word}如果变量名存在且非null,则返回word,否则返回ull
用途:测试变量是否存在。
范例:${value:+word},如果value已经定义,则返回word(也就是真)
bash特性之多shell命令执行
命令 1;命令2;命令3;。。。。
set 查看设置的变量
set 变量名=value 设置变量
unset 变量 撤销变量,服务器的资源有限,在程序执行完成后,变量或者数据库连接资源必须关闭。
注意shell脚本是运行一个shell进程实现的
bash的配置文件
两类:
profile类:为交互式登录的shell进程提供配置 交互式如:su – root
bashrc类:为非交互式登录的shell进程提供配置 非交互式:1. su root
2.图形界面打开的终端 3.运行的脚本等
profile类:
全局:对所有用户都生效
/etc/profile /etc/profile.d/*.sh(自己自己创建shell脚本)
用户个人的:仅对个人有效
~/.bashprofile
功用:
1.用于定义环境变量 2.运行命令或脚本
bashrc
全局:对所有用户都生效
/etc/bashrc
用户个人的:仅对个人有效
~/.bashrc
功用:
1.定义本地变量 2.定义命令别名
注意:仅管理员可修改全局配置文件
配置文件读取顺序
交互是登录shell进程:
/etc/profile–>/etc/profile.d/*–>~/.bash_profile—>~/.bashrc—>/etc/bashrc
非交互式登录shell进程:
~/.bahrc–>/etc/bashrc–> /etc/profile.d/*
命令行中定义的特性,例如变量和别人作用域为当前shell进程的生命周期
配置文件定义的特性,只对随后新启动的shell进程有效
让配置文件加载方法
(1)重新登录系统
(2)通过bash执行: .配置文件 重读配置文件
(3)让shell进程重读配置文件: source 配置文件
实例:vim /etc/profile.d/xiong.sh
内容为:echo welcome to xiong linux
source /etc/profile.d/xiong.sh
hell脚本编程大致分两类,根据运行方式:
编译运行:源代码–>编译器转换为程序文件,然后才能运行 tar -zxvf test.tar.gz make&&make install
解释运行:源代码–>运行时启动解释器,由解释器边解释变运行
程序执行过程:
过程式: 顺序执行,选择执行,循环执行
对象式:首先定义对象,在用顺序执行,选择执行,循环执行
shell脚本规范: #为注释符
shell脚本第一行要写shell脚本的解释器 #!/bin/bash 指定shell脚本的解释器
第二行:#shell编写者,编写时间,联系方式
第三行#注释shell脚本作用等等
运行shell脚本
1.sh shell.sh 不需要执行权限 2. ./shell.sh 脚本shell.sh必须要有执行权限
3.bash shell.sh 脚本shell.sh必须要有执行权限
4.sh -x 脚本 或者bash -x 脚本 ,显示脚本执行的过程,便于用户调试程序bug
time命令 显示shell程序执行的时间,用测试程序反应时间
逻辑运算
true为真,用1表示。 false为假,用0表示
逻辑与: 逻辑或: 逻辑非:
1与1=1 1或1=1 !1=0
1与0=0 1或0=1 !0=1
0与1=0 0或1=1
0与0=0 0或0=0
短路运算:
短路运算: 短路或运算: 短路异或:^
第一个为0,结果必定为0 第一个为1,结果必定为1; 异或的两个值,相同为假,不同为真
第一个为1,第二个必须要参与运算; 第一个为0,第二个必须要参与运算;
聚集命令的方法:
复合式,用分号隔开,如 date; who | wc -l
命令会一个接一个地运行
子shell:(date; who | wc -l ) >>/tmp/trace 所有的输出都被发送给单个STDOUT和STDERR
退出状态码
进程使用退出状态来报告进程的执行成功或者失败
0 代表成功,1-255代表失败
$? 变量保存最近的命令退出状态
示例:
自定义退出状态码,用于捕捉摸个进程的执行状态
exit [n]:自定义退出状态码;
注意: (1)脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
(2)如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
示例:
条件测试:
判断某需求是否满足,需要由测试机制来实现, 专用的测试表达式需要由测试命令辅助完成测试过程;
评估布尔声明,以便用在条件性执行中
如果条件为真,则返回0 否则则返回1
测试命令模型:
test 表达式 长格式 如: test $a -eq $b
[ 表达式 ] 短格式 如: [ $a -eq $b ]
[[ 表达式 ]] 如: [[ $a -eq $b ]]
注意:表达式前后必须有空白字符
条件性的执行操作符
根据退出状态而定,命令可以有条件地运行
&& 代表条件性的AND THEN 实例: grep -q batman /etc/passwd || echo "no such batman"
|| 代表条件性的OR ELSE 实例:ping 10.1.0.2 -c 4 &> /dev/null && echo "10.1.0.1 is up" || echo "10.1.0.1 is down"
组合测试条件
第一种方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
第二种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行; [ $USER == "root" -a -e "/etc/issue" ] && sed -n "/^#[[:space:]][[:alnum:]]\+/p" /etc/fstab
bash数值计算符(用于shell数值变量计算) 注意linux对于有小数计算时,需要用bc命令
1.基本运算符
+(加) -(减) *(乘) /(除)
%(取余或者叫做取模,如:4%3=1) **( 乘方)
2.增强运算符
+= 如: a+=2等于a=a+2
-= 如: a-=2等于a=a-2
*= 如 : a*=2等于a=a*2
/= 如 : a/=2等于a=a/2
%= 如: a%/2等于a=a%2
a++ 等于a,下一次则是a+1 a–等于a,下一次则是a-1
++a –a 记忆方法:变量再前,先输出变量值,变量再后,就是先运算后再输出变量制的值。
3.数值运算
(1) let var=算术表达式 (2) var =$[算术表达式] (3) var =$((算术表达式))
(4)var=$(expr arg1+arg2) (5)declare -i var=数值 (6) echo '算术表达式' | bc
4.数值测试:
测试格式: (1) test 表达式 (2) [ 表达式 ] 注意有空格 (3) [[ 表达式 ]] 注意空格
数值测试类型 ,执行状态:0位真,1为假
(1) -eq 等于 [ a -eq b ] , 如果a=b,则执行状态为真 ,否则执行状态为假
(2) -ne 不等于 [ a -ne b ] , 如果a!=b,则执行状态为真 ,否则执行状态为假
(3) -gt 大于 [ a -gt b ], 如果a>b,则执行状态为真,否则执行状态为假
(4) -ge 大于等于 [ a -ge b ] ,如果a>=b,则执行状态为真,否则执行状态为假
(5) -lt 小于 [ a -lt b ] ,如果 a<b,则执行状态为真,否则执行状态为假
(6) -le 小于等于 [ a -le b ] ,如果a<=b,则执行状态为真,否则为假
字符串测试 注意:1.字符串用> ,<符号比较是需要加转义字符'\',不然系统为认为是重定向等.2字符变量最好用${变量}或者"$变量"
(1) == 或 = : 测试字符串是否相等,如 a="xiong",b="xiong" ;[ $a == $b ] ,如果a等于b字符串,则执行状态为真,否则为假
(2) > 字符串1ascii码是否大于字符串2ascii码 ,如 [ a > b ] ,如果a的ascii码大于b的ascii码,则执行状态为真,否则为假
(3) < 字符串1ascii码是否小于字符串2ascii码 ,如 [ a < b ] ,如果a的ascii码小于b的ascii码,则执行状态为真,否则为假
(4) != 测试字符串不相等,[ $a != $b ] ,如果a字符串不等于b,则执行状态为真,否则为假
(5) =~ 左侧字符串是否能够被右侧的pattern所匹配;注意,注意:此表达式一般用于[[ ]]中
(6) -z string : 字符串为空,则为真,否则为假
(7) -n string :字符串不空,则为真,否则为假
文件测试
存在性测试
-a FILE:同-e
-e FILE: 文件存在性测试,存在为真,否则为假;
存在性及类别测试
-b FILE:是否存在且为块设备文件;
-c FILE:是否存在且为字符设备文件;
-d FILE:是否存在且为目录文件;
-f FILE:是否存在且为普通文件;
-h FILE 或-L FILE:存在且为符号链接文件;
-p FILE:是否存在且为命名管道文件;
-S FILE:是否存在且为套接字文件;
文件权限测试:
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-g FILE:是否存在且拥有sgid权限;
-u FILE:是否存在且拥有suid权限;
-k FILE:是否存在且拥有sticky权限;
文件属组测试
-t fd: fd表示文件描述符是否已经打开且与某终端相关
-N FILE:文件自动上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
文件大小测试:
文件是否为空测试
-s FILE: 是否存在且非空;
文件对比测试,也叫双目测试:
FILE1 -ef FILE2: FILE1与FILE2是否指向同一个设备上的相同inode
FILE1 -nt FILE2: FILE1是否新于FILE2;
FILE1 -ot FILE2: FILE1是否旧于FILE2;
20160810作业
一、脚本
1、编写脚本/root/bin/,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。
#!/bin/bash
hname=`hostname`
ipaddr=`ifconfig | sed -n '2p' | cut -d ':' -f 2 | cut -d ' ' -f 1`
osversion=`cat /etc/issue | head -1`
linuxKernel=`uname -r`
linuxCup=`lscpu | grep 'Model[^:].*' | tr -s ' '| cut -d : -f 2 | tr -s ' '`
linuxhard=`lsblk | sed -n 3p | grep -o "\<[0-9]\+[G]\>"`
linuxme1=`free -h | grep "^[[:alpha:]].*" | tr -s ' ' | cut -d ' ' -f 1,2 | tr '\n' ' ' | cut -d ' ' -f2`
linuxme2=`free -h | grep "^[[:alpha:]].*" | tr -s ' ' | cut -d ' ' -f 1,2 | tr '\n' ' ' | cut -d ' ' -f4`
echo "主机名:$hname 主机IP:$ipaddr"
echo "系统版本:$osversion 系统内核版本:$linuxKernel"
echo "cpu型号:$linuxCup 硬盘大小:$linuxhard"
echo "内存:$linuxme1 共享内存:$linuxme2"
2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中
实现自动换备份
下面shell脚本是以每分钟备份的
#!/bin/bash
#author QQ:111111111
backTime=`date +%F-%M`
cronDir=/var/spool/cron/root
cp -r /etc/ /root/etc$backTime
#通过echo输入crontab任务,可见自动执行创建任务,但是系统可能有警告
if [ -e $cronDir ];then
#task=`grep "backup.sh" $cronDir | cut -d ' ' -f 7`
task=`grep "backup" $cronDir | wc -l`
if [ $task -eq 0 ];then
echo "*/1 * * * * /bin/bash /root/backup.sh" >> $cronDir
echo "backup任务已经创建。"
else
echo "backup已经存在"
fi
fi
3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
#!/bin/bash
#author QQ:111111111
dUser=`df -h | grep "^\/" | tr -s ' ' | tr -d '%' | sort -t ' ' -k 5nr | head -n 1 |cut -d ' ' -f 5`
diskno=`df -h | grep "^\/" | tr -s ' ' | tr -d '%' | sort -t ' ' -k 5nr | head -n 1 |cut -d ' ' -f 6`
echo "$diskno: $dUser%"
4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序
#!/bin/bash 系统坏了,写的shell没了,赶作业弄个简单版
#author QQ:111111111
netstat -tan | grep "ESTABLISHED" | awk '{print $5}'| cut -d: -f1|sort|uniq -c
5、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的
#!/bin/bash
#author QQ:111111111
var1=`cat /etc/passwd | sed -n "10p"|cut -d: -f3`
var2=`cat /etc/passwd | sed -n "20p"|cut -d: -f3`
let var3=var1+var2
echo "5、第10个用户和第20用户的ID之和:$var3"
6、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
#!/bin/bash
#author QQ:111111111
file1=`grep "^$" $1 |wc -l`
file2=`grep "^$" $2 |wc -l`
file3=$[file1+file2]
echo "$1,$2两个文件中所有空白行之和:$file3"
7、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件
#!/bin/bash
#author QQ:111111111
dirNum=`ls -l /etc/ /var/ /usr/ | cut -c1|sort | uniq -c | grep '-'| tr -s ' '| tr -d '-'
`
fileNum=`ls -l /etc/ /var/ /usr/ | cut -c1|sort | uniq -c | grep 'd'| tr -s ' '| tr -d 'd'
`
echo "文件有:$fileNum,目录有:$dirNum"
8、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;
如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
#!/bin/bash
#author:maoxiong QQ:111111111
#verson:1.0 date:2016-08
#illustrate:Comparison numbe
[[ $# -lt 1 ]] && echo "输入参数小于 1" || (echo "文件中空白行为:";grep -c '^[[:space:]]*$' $1)
9、写一个脚本/root/bin/,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”
;如果不可ping通,则提示用户“该IP地址不可访问”
#!/bin/bash
#author QQ:111111111
read -p "请输入需要检查的ip地址:" ipaddr
ping $ipaddr -c 2 &> /dev/null && echo "该$ipaddr地址可以访问"||echo "该$ipaddr地址不可访问"
10、判断硬盘的每个分区空间和inode的利用率是否大于80,如果是,发邮件通知root磁盘满
11、指定文件做为参数,判断文件是否为.sh后缀,如果是,添加x权限
#!/bin/bash
#author QQ:111111111
read -p "请输入文件:" file
echo $file | grep -o ".sh$" &> /dev/null
num=0
[ $statusNum -eq $num ] && (chmod a+x $file ;echo "$file文件存在") || echo "$file文件不存在"
13、计算1+2+3+…+100
#!/bin/bash
#author QQ:111111111
read -p "请输入连续累加起始值:" var1
read -p "请输入连续累加结束值:" var2
num1=$var1
num2=$var2
let num3=(num1+num2)*num2/2
echo "$num1至$num2累加总合是:$num3"
14、输入起始值A和最后值B,A大于B,计算从A+(A+1)…+(B-1)+B的总和
#!/bin/bash
#author QQ:111111111
read -p "请输入A值:" var1
read -p "请输入B值:" var2
a=$var1
b=$var2
[ $a -lt $b ] && echo "A+..+B=`seq -s+ $a $b | bc`" || echo "A>B,请重新输入"
原创文章,作者:maoxiong,如若转载,请注明出处:http://www.178linux.com/34529
评论列表(1条)
总结的很详细,排版也很工整,态度公正,望以后的博客能按时提交。