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)
上一篇 2016-08-15 09:25
下一篇 2016-08-15 09:25

相关推荐

  • linux基础入门常识

    1、计算机的组成及功能 控制器:对程序规定的控制信息进行解释,根据其要求进行控制,调度程序、数据、地址,协调计算机各部分工作及内存与外设的访问等。 运算器:对数据进行各种算术运算和逻辑运算。 存储:存储程序、数据和各种信号、命令等信息。 输入:将程序、数据、字符、控制命令等信息输入到计算机进行处理。 输出:将计算机处理过的数据或信号输出出来。 2、linux…

    Linux干货 2017-12-03
  • linux系统创建主分区、逻辑分区 、设置ext系列分区的参数以及检测分区

    使用到的命令有:fdisk分区管理命令、partx 强制内核更新分区表(通过查看/procs/partitions文件可知道内核没有更新新创建的分区)、mkfs格式化分区命令、mke2fs格式化etx专用工具、blkid查看分区属性、fsck测试分区    linux对不同的磁盘设备的设备文件命名如下:    &nbs…

    Linux干货 2016-05-16
  • RPM总结(一)

    软件包基础软件包运行环境硬件、内核、应用程序的关系包管理器程序包管理器Linux不同系统上的包管理器RPM的优点rpm包命名方式一般源代码的命名rpm包的命名rpm包的分类与拆包包管理工具RPM包管理器:程序包管理器:获取程序包的途径:rpm包管理CentOS系统上使用rpm命令管理程序包:安装升级:降级降级实例more 软件包基础 包管理过程中,最常用的操…

    Linux干货 2016-08-24
  • Linux下/proc目录详解

    Linux下/proc目录详解 proc目录总的概述 proc下有关进程的目录概述 proc下针对Linux系统相关的参数目录概述 /proc目录总的概述 1.首先,我们可以使用ll命令查看下/proc目录,如下 [root@centos6 ~]# ls -l /proc total 0 dr-xr-xr-x. 8 root root 0 May 19 04…

    Linux干货 2017-05-20
  • 图解Man

    个人浅见 欢迎指正

    Linux干货 2016-10-18
  • Linux目录结构

    Linux目录结构 查看目录(/) 树状目录结构: 常见目录的解释 Linux 下的文件类型 路径 Linux目录结构 查看目录(/) 登录系统后,在当前命令窗口下输入命令: [root@localhost ~]# ls /bin   dev  home  lib64       media &nb…

    Linux干货 2016-09-06

评论列表(1条)

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

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