shell 编程


1 基础正则表达式

1 正在表达式与通配符

正则用来匹配字符串的grep、awk、sed等命令可以支持正则表达式  包含匹配

通配符 * ?[] 用来匹配文件名 ls、find、cp这些命令不支持正则   完全匹配

2 基础正则表达式 * . ^ $ [] [^] \  \{n\} \{n,\} \{n,m\}  

* 前一个字符匹配0次或任意多次

. 匹配除了换行符外任意一个字符

^ 匹配行首

$ 匹配行尾

[] 匹配括号内的任意一个字符

[^a-z]  a\{2,9\}

注意: a*  类似于匹配整片文档  aa* 才是真正匹配a的

.   匹配任意字符

.*  匹配任意多个字符 除了换行符

^$  匹配空白行

[a-zA-Z] 全部字符

[^a-zA-Z] 全部非字符


2 字符截取命令

1 grep cut 命令  分别 行 列

2 cut 命令提取列 信息  基本用法:cut -f 2 sutdent.txt  默认分隔符 Tab 制表符

cut -d ':' -f 1,3 /etc/password    说明:-d  指定分隔符  -f 指定 列

例子: [root@bogon ~]# cat /etc/passwd | grep /bin/bash | grep -v root | cut -d ':'  -f 1

lizhiling

lijingshan

无法支持 空格作为分隔符

3 df 命令  用法:df -h


22 printf命令

格式化 打印 命令  输出类型输出格式

%ns:   输出n个字符串

%ni: 输出n个数字

%m.nf: 输出m位,其中n个小数

\n \r \t \a 等格式调整

用法实例:[root@bogon ~]# printf '%s %s %s\n' $(cat anaconda-ks.cfg)  三个一组


33 awk 命令

1 支持 print 跟 printf ,其中print 不在linux里面用

2 其实是 awk 编程  职称函数

#awk '条件1 {动作1}  条件2 {动作2}...' 文件名

BEGIN   开始前执行的命令

FS 内置变量   分隔符  其中 可以同时使用  BEGIN FS 否则第一行不处理

END   所有的数据都处理完成后,执行 END 命令

3 awk 直接显示截取结果

44 sed 命令

轻量级流编辑器  

格式: sed [选项] '[动作]' 文件名

选项:

-n 输出到屏幕

-e 允许对输入数据应用多条sed命令编辑

-i 用sed的修改结构直接修改读取数据的文件,而不是由屏幕输出

动作:

a\: 追加

c\: 行替换

i\: 插入

d 删除

p: 打印

s: 字串替换

3 字符处理命令

1 排序命令 sort

[root@localhost~]#sort [选项] 文件名

选项

-f: 忽略大小写

-n: 以数值型进行排序,默认使用字符串型排序

-r: 反向排序

-t: 指定分隔符,默认是分隔符是制表符

-k n[,m]: 按指定的字段范围排序。从第n字段开始,m字段结束(默认到行尾部)

2 统计命令 wc

[root@localhost~]#wc[选项]文件名

选项:

-l: 只统计行数

-w: 只统计单词数

-m: 只统计字符数

4 条件判断

1:按照文件类型进行判断

-b文件: 判断文件是否存在,并且是否为块设备文件(是块设备文件为真)

-c文件: 判断文件是否存在,并且是否为字符设备文件(是字符设备文件为真)

-d文件: 判断文件是否存在,并且是否为目录文件(是目录为真)

-e文件: 判断文件是否存在(存在为真)

-f文件: 判断文件是否存在,并且是否为普通文件(是普通文件为真)

-L(大写)文件: 判断文件是否存在,并且是否为符号链接文件(是符号链接文件为真)

-p文件: 判断文件是否存在,并且是否为管道文件(是管道文件为真)

-s文件: 判断文件是否存在,并且是否为非空(非空为真)

-S(大写)文件: 判断文件是否存在,并且是否未套接字文件(是套接字文件为真)


两种判断格式:

1: [root@localhost~] test -e /root/install.log

[root@bogon ~]# echo $? 0代表上一条命令的返回结果正确

2: [root@localhost~] [空格-e空格/root/install.log空格]

脚本中常用 中括号

[-d /root] && echo 'yes' || echo 'no'

2 按照文件权限进行判断  三者只要有一个人有这个权限就执行

-r文件: 判读该文件是否存在,并且该文件拥有读权限(有读权限为真)

-w文件: 判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真)

-x文件: 判读该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真)

-u文件: 判断该文件是否存在,并且该文件是否拥有SUID权限(有SUID权限为真)

-g文件: 判断该文件是否存在,并且是否该文件拥有SGID权限(有SGID权限为真)

-k文件: 判断该文件是否存在,并且是否该文件拥有SBit权限(有SBit权限为真)

3 两个文件之间进行比较

文件1 -nt 文件2 判断文件1的修改时间是否比文件2的新(如果新则为真)

文件1 -ot 文件2 判断文件1的修改时间是否比文件2的旧(如果旧则为真)

文件1 -ef 文件2 判断文件1和文件2的inode号一致,可以理解为两个文件是否为同一个文件,这个是判断硬链接的方法

4 两个整数之间的比较

整数1 -eq 整数2 判断整数1是否和整数2相等(相等为真)

整数1 -ne 整数2 判断整数1是否和整数2不相等(不相等为真)

整数1 -gt 整数2 判断整数1是否大于整数2(大于为真)

整数1 -lt 整数2 判断整数1是否小于整数2(小于为真)

整数1 -ge 整数2 判断整数1是否大于等于整数2(大于等于为真)

整数1 -le 整数2 判断整数1是否小于等于整数2(小于等于为真) 

5 两个字符串的判断

-z 字符串 判断字符串是否为空(为空返回真)

-n 字符串 判断字符串是否为非空(非空返回真)

字符串1 == 字符串2 判断字符串1 和 字符串2相等 (相等返回真)

字符串1 != 字符串2 判断字符串1和字符串2不相等 (不相等返回真)

6 多重条件判断

判断1 -a 判断2 逻辑与,判断1和判断2都成立,最终的结果才为真

判断1 -o 判断2 逻辑或,判断1和判断2有一个成立,最终的结果就为真

!判断 逻辑非,是原始的判读取反


5 流程控制

1 if语句

test 或者 []

1 单分支if条件语句

if [空格条件判断式空格];then

程序

fi

或者

if [ 条件判断式 ]

then

程序

fi

注意:

1 if开头 fi结尾,

2 [条件判断式] 就是使用 test命令判断,所以中括号和条件判断式之间必须有空格

3 then 后面跟符合条件之后执行的程序,可以放在[]之后,用户“:”分割。也可以换行写入,就不需要":"了


例子:

#!/bin/bash

#统计根分区使用率

#Author: shenchao (E-mail:shenchao@lampbrother.net)

rate=$(df -h | gep "/dev/sda3" | awk '{print $5}' | cut -d "%" -f1)

#把根分区使用率作为变量赋值到变量rate

if [ $rate -ge 80 ]

then

echo "Warning! /dev/sda3 is full!!"

fi

2 双分支if条件语句

if [ 添加判断式 ]

then 

条件成立时,执行的程序

else

条件不成立时,执行的另一个程序

fi

例子1:备份mysql数据库

##################################################################################################

#!/bin/bash

#备份mysql数据库

#Author:shenchao (E-mail:shenchao@lampbrother.net)


ntpdate asia.pool.ntp.org &>/de/null

#同步系统时间


date=$(date+%y%m%d)

#把当前系统时间按照“年月日”格式赋值变量date


size=$(du -sh /var/lib/mysql)

#统计mysql数据库的大小,并把大小赋值size变量


if [ -d /tmp/dbbak ]

        then

                echo "Date:$date" > /tmp/dbbak/dbinfo.txt

                echo "Data size:$size" >> /tmp/dbbak/dbinfo.txt

                cd /tmp/dbbak

                tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &> /dev/null

                rm -rf /tmp/dbbak/dbinfo.txt

        else

                mkdir /tmp/dbbak

                echo "Date:$date" > /tmp/dbbak/dbinfo.txt

                echo "Data size :$size" >> /tmp/dbbak/dbinfo.txt

                cd /tmp/dbbak

                tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &> /dev/null

                rm -rf /tmp/dbbak/dbinfo.txt

fi

###################################################################################################

3 多分支if条件语句

if [ 条件判断式1 ]

then 

当条件判断式1成立时,执行程序1  建议增加 eixt 1  此时的1为错误的返回数值  可以用$?查看

elif [ 条件判断式2 ]

then

当条件判断式2成立时,执行程序2 建议增加 eixt 2  此时的2为错误的返回数值  可以用$?查看

....省略更多....

else

当所有条件都不成立时,最后执行此程序

fi

2 case语句

语法:

case $变量名 in

"值1")

如果变量的值等于值1,则执行程序1

;;

"值2")

如果变量的值等于值2,则执行程序2

;;

...胜利其它分支...

*)

如果变量的值都不是以上的值,则执行此程序

;;

esac

注意: ;; 双分号,  esac 结尾

3 for循环

语法:  方式1 不确定循环次数

for 变量 in 值1 值2 值3 ....

do 

程序

done

说明: 将后面的数值依次赋值给变量进行执行,依靠空格 进行输入值区分,换行符也可以


语法:方式2

for((初始值;循环控制条件;变量变化))

do

程序

done

例子:

s=0

for((i=1;i<=100;i=i+1))

do 

s=$(($s+$i))

done

echo "The sum is"$s

4 while循环 

语法:

while [条件判断式]

do

程序

done

2 until 循环

语法:循环条件成立 就终止


until [条件判断式]

do

程序

done

脚本语言,所见即所得。不需要编译,坏处,就是执行较慢