shell编程之变量,数值计算,字符比较,文件测试小记

 变量 

   变量:能储存计算结果或能表示值抽象概念,其指向的内存空间中一段地址。    

   变量赋值: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
      file://C:\Users\tom\AppData\Local\Temp\ct_tmp/1.png
     
    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
       file://C:\Users\tom\AppData\Local\Temp\ct_tmp/2.png  
       可以用:export,printenv,env,delclare -x查看系统环境变量,撤销环境变量用:unset 变量
   
    3.只读变量:
         declare -r 变量,readonly 变量  ,只读无法重新赋值,不支持撤销,随shell进程终止而终止。
         file://C:\Users\tom\AppData\Local\Temp\ct_tmp/3.png
 
    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脚本参数总个数
    $*所有参数
    $@所有参数
    file://C:\Users\tom\AppData\Local\Temp\ct_tmp/4.png
   
    $?获取当前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。
    file://C:\Users\tom\AppData\Local\Temp\ct_tmp/5.png
   
    变量=${man:=word}如果变量名存在且非null,则返回变量值。否则,设置这个变量值为word,并返回其值。
    用途:如果变量未定义,则设置变量为默认值,并返回默认值。
     result=${man:=set} 如果man没有值,则将unset值赋给man,在将值赋给result
     file://C:\Users\tom\AppData\Local\Temp\ct_tmp/6.png
     
     变量=${man:?"not defined}如果变量名存在且非null,则返回变量的值。否则显示变量名:message,并退出当前的命令或者脚本。用途:用于捕捉由于变量未定义而导致的错误,并退出程序
     result=${man:?word} 如变量man存在,则返回word,否则返回空
      file://C:\Users\tom\AppData\Local\Temp\ct_tmp/7.png

     变量=${value:+word}如果变量名存在且非null,则返回word,否则返回ull
     用途:测试变量是否存在。
     范例:${value:+word},如果value已经定义,则返回word(也就是真)
    file://C:\Users\tom\AppData\Local\Temp\ct_tmp/8.png
   
   
    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程序执行的时间,用测试程序反应时间

图片1.png


逻辑运算
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代表失败
$? 变量保存最近的命令退出状态
示例:

图片3.png
自定义退出状态码,用于捕捉摸个进程的执行状态
exit [n]:自定义退出状态码;
注意: (1)脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
(2)如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
示例:
图片4.png条件测试:
判断某需求是否满足,需要由测试机制来实现, 专用的测试表达式需要由测试命令辅助完成测试过程;
评估布尔声明,以便用在条件性执行中
如果条件为真,则返回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"
图片5.png


组合测试条件
第一种方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
图片7.png
第二种方式:
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) **( 乘方)
图片8.png
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
图片9.png
a++ 等于a,下一次则是a+1 a–等于a,下一次则是a-1
图片10.png++a –a 记忆方法:变量再前,先输出变量值,变量再后,就是先运算后再输出变量制的值。

图片11.png

3.数值运算
(1) let var=算术表达式 (2) var =$[算术表达式] (3) var =$((算术表达式))
(4)var=$(expr arg1+arg2) (5)declare -i var=数值 (6) echo '算术表达式' | bc
图片12.png

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,则执行状态为真,否则为假
图片13.png

字符串测试 注意: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 :字符串不空,则为真,否则为假
图片14.png


文件测试
存在性测试
-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;
图片15.png

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"

图片16.png

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

图片17.png 

 

 

 

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%"

 图片18.png

 

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

图片19.png

 

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"

 图片20.png

 

 

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"

图片21.png

 

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"

图片22.png 

 

8、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;

如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数

#!/bin/bash

#author:maoxiong QQ:111111111

#verson:1.0  date:2016-08

#illustrate:Comparison numbe

图片6.png

[[ $# -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地址不可访问"

 图片1.png

 

 

 

 

10、判断硬盘的每个分区空间和inode的利用率是否大于80,如果是,发邮件通知root磁盘满

图片2.png 

 

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文件不存在"

图片3.png 

 

 

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"

图片4.png

 

 

 

14、输入起始值A和最后值BA大于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,请重新输入"

 

图片5.png

 

    file://C:\Users\tom\AppData\Local\Temp\ct_tmp/9.png    

原创文章,作者:maoxiong,如若转载,请注明出处:http://www.178linux.com/34529

(0)
maoxiongmaoxiong
上一篇 2016-08-15
下一篇 2016-08-15

相关推荐

  • 浅述vim操作

    vim是一种比vi更加强大的模式化的全屏文本编辑器。vim在工作过程中有三种模式:编辑模式、插入模式、末行模式。 编辑模式(默认):又称命令模式,其工作内容包括移动光标、剪切、粘贴、删除等 输入模式:亦可称为插入模式,主要是在文件中修改文本内容 末行模式:亦称扩展命令模式,主要是执行vim内置命令的 vim三种模式之间的切换:如下图   (1)编辑…

    Linux干货 2016-08-11
  • rpm包管理、yum仓库、ftp、http服务、编译安装

    一、软件包管理 1.1 软件包管理 API:Application Programming Interface  应用程序开发接口;程序员面对的编程接口 POSIX:portable operating system:可移植操作系统接口 v   程序源代码 –> 预处理 …

    Linux干货 2016-11-27
  • 任务计划使用方法

    概述     任务计划其实就是针对未来的某一刻或者是某一周期内设置要执行的工作;     任务计划分为两种:         1、一次性任务:在指定的未来的某个时间点仅执行一次任务;  &n…

    Linux干货 2015-03-26
  • linux中常用文本处理工具

       在linux文件系统中经常会使用到文本处理工具,这里简单介绍几种文本处理工具: 抽取文本的工具 文件内容:less和cat 文件截取:head和tail 按列抽取:cut 按关键字抽取:grep , egrep 文件查看命令:cat, tac,rev,more,less   cat命令是用户经常使用的用来查看文本…

    Linux干货 2016-08-07
  • Linux之bash shell脚本编程入门篇(三)之循环以及函数function的使用

    bash shell脚本编程入门篇(三)之循环 什么是循环执行?     将某代码段重复运行多次     重复运行多少次:         循环次数事先已知    &nb…

    Linux干货 2016-08-22
  • heartbeat实现高可用集群(2)

    [[ heartbeat v2 + crm ]] 环境 node1 192.168.1.35 node2 192.168.1.36 fip 192.168.1.81 daemon httpd ha web service ip httpd node1&2 # vim ha.cf crm on # cd # rpm -ivh heartbeat-gui…

    Linux干货 2017-11-03

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-15 09:36

    总结的很详细,排版也很工整,态度公正,望以后的博客能按时提交。