shell脚本知识储备汇总

语言类型

强类型:定义变量必须指定类型;参与的运算必须要符合类型要求(字符串不能和数值相加等);调用未声明变量会报错弱类型:定义变量无需指定类型;默认为字符型参与运算时会自动进行类型转换;变量无需事先定义也可调用(空)

解释器:

shell是解释器bash是可用的具体解释器(shell是车这个概念bash是宝马车)bash  sh ksh(需自己安装) tcsh csh等   bash的基本特性:快捷键;Tab补齐命令和路径;history;命令别名;标准输入输出;重定向;管道;Redhat6选项不可Tab  需要装bash-completion这个包才能Tab更改用户shell环境(解释器):  useradd -s 创建用户时usermod -s 改已存在用户vim /etc/passwd 改配置history:查看条数: grep HISTSIZE /etc/profileecho $HISTSIZEhistory | wc -lhistory | tail调用:        !1028!cat清空(两条命令必须同时执行):history -c > ~/.bash_history  空重定向到HISTFILE文件别名alias:    grep '^alias' ~/.bashrc 家目录下的隐藏文件unalias 取消

重定向:

>    (正确覆盖输出);>>   (正确追加输出);2>   (错误覆盖输出);2>>  (错误覆盖输出);&>       (正确错误覆盖输出);&>>      (正确错误追加输出);>&2      把正确变成错误输出<;  (导入文件)  tips:   写脚本可以上来就date >(>>) xx.log  再在里面把命令执行错误的信息2>(>>) xx.log以执行时间    进行区分了方便查看某次执行时的错误非交互式写邮件三种:mail -s biaoti user <<EOFXXYYEOFecho haha | mail -s biaoti user  管道mail -s biaoti user < mail.txt   导入写好文件

脚本的执行方式:

    /root/first.sh   ./first.sh     绝对路径(相对)执行      需+xbash、sh /root/first.sh      解释器执行(相当于作为参数)不需+x  开了子进程pstree可以验证source、./root/first.sh      解释器执行(相当于作为参数)  不需+x  当前进程执行用于使改的配置马上生效而不重启,相当于重读配置文件。

shell变量:

变量的类型储值类型:数值型  :整数型;浮点型;复数。。。字符型  :生效范围:本地变量:当前Shell环境中有效,而在子Shell环境中无法直接使用 局部变量:全局变量:使用类型:自定义变量:  a=1 echo ${a}10  110 本地变量TIPS:查看变量时,若变量名称与后面要输出的字符串连在一起,则应该以{}将变量名括起来以便区分环境变量:   PWD、USER、HOME、SHELL、HISTSIZE、HISTFILE、PATH、PS1一级提示符、PS2二级提示符、LOGNAME登录名 RANDOM HOSTNAME TERM记录终端类型环境变量相关文件:(注意开机时读取文件顺序)全局文件为/etc/profile,对所有用户有效   用户文件为~/.bash_profile,仅对指定的用户有效env可查看所有环境变量:set可查看所有变量  位置变量:   $1、$2、$10、……预定义变量:  $0、$$、$?、$#、$*、$@   #!/bin/bashecho $0                                        //脚本的名称echo $1                                        //第一个参数echo $2                                        //第二个参数echo $*                                        //所有参数 当成一个整体字符串echo $@                                          //所有参数 每个参数为独立字符串echo $#                                        //输入的位置变量个数echo $$                                        //当前进程的进程号echo $?                                        //上一个命令执行状态返回值echo  $!                                       // 最后一个后台进程的进程号shift 3                                                    //换岗 踢掉参数(默认为一个)使用read命令从键盘读取变量值read -p "请输入。。:" i  用户输入的值赋予变量i将回显功能关闭(stty -echo)  输password时将回显功能恢复(stty echo)   输完password时使用export发布全局变量  export PATH="$PATH:/usr/local/haha/bin"临时加了个可执行路径。export XX="1234" 变量的定义:  名称只能为字母数字下划线且只能以字母和下划线开头a=123       字符串a=$b        引用其他变量的值为自己的值a=$(date)   命令结果引用为自己的值三种引号对赋值的影响:强引用:    双引号       界定一个完整字符串弱引用:    单引号         界定一个完整的字符串且屏蔽特殊符号命令结果引用:  反撇号或$()    引用命令执行的结果赋予变量       变量的调用调用变量时,若变量名称与后面输出的字符串连在一起,以{}将变量名括起来以便区分

shell的数值运算

整数运算:expr                 \*$[]或$(())       运算符两侧可以无空格  引用变量可省略 $let                 不显示结果expr或$[]、$(())方式只进行运算,并不会改变变量的值;而let命令可以直接对变量值做运算再保存新的值let X++ X-- X+=7 X-=7 X*=7 X/=7 X%=7  强大!!小数运算:bc      scale=N 小数位的长度echo 'scale=4;12.34-5.678' | bc 6.662  虽然小数位长为4但运算数值最长为3 也只显示3位。tips:bc支持条件测试正确返回1错误返回0 与$?相反

条件测试

“test 表达式”或者[ 表达式 ]都可以,表达式两边至少要留一个空格。注意空格空格空格![  $USER == "root"  ] 等号两边有空格(没有就相当字符串a) 表达式和[]间有空格!!!字符串匹配==  !=  -z 检查变量的值是否为空      -n或!-z 检查变量的值是否非空        比较整数值的大小eq      ne   gt    ge      lt   le识别文件/目录的状态-e存在    -d目录        -f普通文件      -r读 -w写     -x执行多个条件/操作的逻辑组合&&,逻辑与   第一个为假后面都不用执行||, 逻辑或      第一个为真后面都不用执行!,逻辑非短路运算:[ $X -gt 10 ] && echo "YES" || echo "NO"第一个为真必须yes而不会No了,因为前面整体为真了||运算已经结束。或者永远只判断逻辑符号的前一条命令来推导该命令会不会执行。

if选择结构

单分支就直接:     [ $X -gt 10 ] && echo "YES"双分支:               [ $X -gt 10 ] && echo "YES" || echo "NO"if  [ 条件测试 ];then  命令序列1else    命令序列2fi多分支:    if  [ 条件测试 ];then  命令序列1   执行完就exitelif命令序列2   执行完就exitelse   命令序列3   执行完就exitfi案例:检测/media/cdrom目录,若不存在则创建检测并判断指定的主机是否可ping通ping -c 3 -i 0.2 -W 3 192.168.4.5   -c 3(3次)-i0.2间隔0.2秒-W 3反馈的超时秒数3从键盘读取一个论坛积分,判断论坛用户等级

被阉割的选择结构case

    case分支属于匹配执行的方式,它针对指定的变量预先设置一个可能的取值,判断该变量的实际取值是否与预设的某一个值相匹配,如果匹配上了,就执行相应的一组操作,如果没有任何值能够匹配,就执行预先设      置的默认操作。case  变量值  in模式1)命令序列1 ;;模式2)命令序列2 ;;    注意格式!!!必须是双分号。。.. ..*)默认命令序列esac#!/bin/bashcase $1 inredhat)                 //可以换成-n-i来代表选项做一个功能强大的命令出来echo "fedora";;fedora)echo "redhat";;*)                                              //默认输出脚本用法echo "用法: $0 {redhat|fedora}"esac

循环结构

for循环for  变量名  in  值列表或 {1..5} 或 `seq 5` 或((i=1;i<=5;i++))do命令序列done几个循环造数工具{1..n}seq 5(1开始到5) seq 2 10(2开始到10)seq 2 2 10(2开始中间跳2;即偶数)seq 1 2 10(奇数)[$RANDOM%10+1] 随机产生1-10的数((i=1;i<=5;i++))  初值1;条件<=5;步长为1案例:利用for循环来检测多个主机的存活状态while循环 while  [条件测试]do命令序列done死循环一般格式 while :do命令序列done通常会写成死循环加退出的格式while :doif[条件判断];then命令序列 && breakdone案例:  提示用户猜测一个随机数,直到才对为止检测192.168.4.0/24网段,列出不在线的主机地址

shell函数

    将一些需重复使用的操作,定义为公共的语句块,即可称为函数。通过使用函数,可以使脚本代码更加简洁,增强易  读性,提高Shell脚本的执行效率相当于一段代码(一串命令)取了一个名字类似定义了alias定义错了直接重新定义会覆盖,类似a=1;a=2后会覆盖前。function  函数名 {命令序列.. ..}函数名() {命令序列.. ..}           mycd(){                        //定义函数> mkdir $1> cd $1> }案例:颜色输出的命令:echo -e "\033[32;41mOK\033[0m"。3X为字体颜色分号隔开4X为背景颜色。#!/bin/bashcecho() {echo –e "\033[$1m$2\033[0m"}cecho 32 OKcecho 33 OKcecho 34 OKcecho 35 OK

中断和退出

break可以结束整个循环;continue结束本次循环,进入下一次循环;exit结束整个脚本、#!/bin/bashfor  i   in   {1..5}do[  $i  -eq  3 ]&& break //这里将break替换为continue,exit分别测试脚本执行效果       echo $idoneecho  Overbreak        12Over  continue   1245Over  exit           12案例:求输入数的和输0退出#!/bin/bashwhile  read  -p  "请输入待累加的整数(0表示结束):"     xdo[ $x -eq 0 ]  &&  breakSUM=$[SUM+x]doneecho "总和是:$SUM"案例:求1-20内所有数的平方跳过非6的倍数#!/bin/bashi=0while  [ $i -le 20 ]dolet i++[ $[i%6] -ne 0 ]  &&  continueecho $[i*i]doneexit 2

文本处理

字符串截取及切割echo $变量名 | cut -b 起始位置-结束位置            echo $phone | cut -b 1-6    1-6echo $phone | cut -b 8-     8到最后echo $phone | cut -b 9      第9个echo $phone | cut -b 3,5,8  第3 5 8个expr substr "$变量名" 起始位置 长度${变量名:起始位置:长度}      截取 (索引位置)   ${phone:0:6} ${phone::6}        ${变量名/old/new}      替换第一个${变量名//old/new}     替换全部${变量名#*关键词} (关键词也删)左向右 最短匹配删除   ${A#*:} 从左侧到第一个:的所有${变量名##*关键词}                           左向右 最长匹配删除   ${A##*:}从左侧到最后一个:的所有        ${变量名%关键词*}                       右向左 最短匹配删除    ${A%:*} 从右侧到第一个:的所有${变量名%%关键词*}                        右向左 最长匹配删除  ${A##*:}从右侧到最后一个:的所有    ${变量名:-初值}                                 有初值就用初值 无初值就用赋予的初值   ${XX:-123}xx无初值就赋予123为初值随机密码    #!/bin/bashx=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789//所有密码的可能性是26+26+10=62(0-61是62个数字)for i in {1..8}donum=$[RANDOM%62]tmp=${x:num:1}pass=${pass}$tmp    字符串相加doneecho $pass改扩展名    touch {a,b,c,d,e,f,g,h,i}.doc#!/bin/bashfor FILE in `ls *.doc($1)`domv $FILE  ${FILE%.*}.txt("$2") (${FILE/doc/txt})  $1换成$2的扩展名done初值的处理   #!/bin/bashread -p "请输入一个正整数:" xx=${x:-1}i=1; SUM=0while [ $i -le $x ]dolet SUM+=ilet i++doneecho "从1到$x的总和是:$SUM"#!/bin/bashread  -p   "请输入用户名:"   userread  -p   "请输入用户名:"   pass[ -z $user ] && exit                    //如果无用户名,则脚本退出pass=${pass:-123456}             //如果用户没有输入密码,则默认密码为123456useradd  $userecho "$pass"  | passwd   --stdin   $passexpect预期交互  :模拟人机交互过程(要提前对交互过程非常熟悉)install  expect#!/bin/bashfor i in 10 11          {1..245} seq 1 254doexpect << EOFspawn ssh -o StrictHostKeyChecking=no 172.25.0.$i   #//创建交互式进程           expect "password:" { send "123456\r" }                         #//自动发送密码expect "#   { send "pwd > /tmp/$user.txt \r" }                 #//发送命令expect "#"  { send "exit\r" }EOFdoneexpect脚本的最后一行默认不执行如果不希望ssh时出现yes/no的提示,远程时使用如下选项:# ssh -o StrictHostKeyChecking=no server0shell数组整体赋值:a=(haha xixi hehe )    a[0]=haha 0是索引值为0的量单个赋值:a[0]=haha  a[1]=xixia[2]=hehe

文本处理三剑客grep

    三剑客都用''单引号!

正则表达式

    字符匹配(单个字符).点             任意单个字符[]               [xyz]    集合,里面的任意单个字符[a-z]          [:lower:][A-Z]         [:upper:][a-Z]         [:alpha:][0-9]        [:digit:][0-9a-Z]  [:alnum:][:space:]   [^]              [^xyz]   集合取反    [^a-z][^A-Z][^a-Z][^0-9][^0-9a-Z]|(扩展)x|y  或者匹配次数        *                前一个字符出现任意次\{n,m\}     前一字符出现n到m次\{n}            前一字符出现n次\{n,\}        前一字符至少出现n次\(\)             保留(复制)后向引用次数匹配(扩展)+             至少出现1次?             出现0次或1次{n}             出现n次{n,}            至少出现n次  {n,m}       出现n到m次{0,m}         至多出现m次位置锚定        ^                         匹配行首(以什么开头)$                        匹配行尾(以什么结尾)\>                     词尾   \<                     词首           \b(扩展)    单词边界^$^[[:space:]]*$ 后向引用()         组合为整体,保留(复制)分组(复制)       ( )复制      \1 \2 \3 粘贴\B      匹配非单词边界“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。?       当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”]而“o+?”将尽可能少地匹配“o”,得到结果 ['o', 'o', 'o', 'o']

正则表达式过滤案例:

        egrep -c '/sbin/nologin$' /etc/passwd = egrep '/sbin/nologin$' /etc/passwd | wc -l  内置了统计功能egrep -vc '/sbin/nologin$' /etc/passwd  egrep -cv '.' /etc/rc.local 统计空行egrep -c '^$' /etc/rc.local 统计空行egrep -c ".*" /etc/httpd/conf/httpd.conf      //总行数egrep -c "#" /etc/httpd/conf/httpd.conf   //含注释的行数egrep -c -v '#|^$'  /etc/httpd/conf/httpd.conf  有效配置行(多数配置文件适用)egrep -v '#|^$'  /etc/httpd/conf/httpd.conf > httpd.conf.min 保存有效配置行egrep  '^ .+|^[^#]' test5-19-1.sh  脚本里真正的有效配置的行?具体情况具体分析啊egrep -m 2 '/sbin/nologin$' /etc/passwd 只显示匹配到的前2行  egrep '.*' /etc/rc.local 匹配所有egrep 'exec(ution)*' /etc/rc.local 包含exec 和execution的行ifconfig | egrep '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' 包含MAC地址MAC03="20:69:74:R2:C5:27"  判断mac地址是否有效echo $MAC03 | egrep -q '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' && echo "有效" || echo "无效"过滤有效的邮箱地址egrep '[0-9a-zA-Z_.]{3,}@[0-9a-zA-Z.-]{2,}(\.[0-9a-zA-Z-]{2,})+' mail.txt sort -t: -k3 -n /etc/passwd |tail -1 | cut -d: -f3  UID最大的用户名精确匹配root用户(3种方式)egrep '^\broot\b' /etc/passwdegrep '^\<root\>' /etc/passwd  awk -F: '$1=="root"' /etc/passwd如果root存在显示它的解释器id root &> /dev/null && egrep '^\broot\b' /etc/passwd | cut -d: -f7id root &> /dev/null && awk -F: '$1=="root"{print $NF}' /etc/passwdegrep '\b[0-9]{2,3}\b' /etc/passwd  2-3位数字某个脚本的有效语句:egrep  '^[^#]' test5-19-1.sh | egrep '[^[:space:]]+.*#.*' 这个好恼火啊egrep  '^[^#]|[^[:space:]]+.*#.*' test5-19-1.sh 用户名同shell名的:egrep '(^\b[a-Z0-9]+\b).*\1$' /etc/passwdsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltbash:x:1005:1025::/home/bash:/bin/bashnologin:x:1008:1028::/home/nologin:/sbin/nologin案例:传递两个文件作为参数给脚本计算这两个文件所有空白行之和  k1=$(egrep "^[[:space:]]*$" $1 | wc -lk2=$(egrep "^[[:space:]]*$" $2 | wc -l  echo "$[k1+k2]" root centos user1用户的默认shell和uid/etc/grub2.cfg文件中某单词后面跟一个小括号的行使用echo输出一个绝对路径egrep找出其基名和目录名ifconfig结果中1-255之间的数值(大量用|或者)ifconfig结果中的IP地址

文本处理三剑客sed:

    逐行处理软件 读一行处理一行 逐行处理读一行处理一行。sed [选项] '条件指令' 文件选项:-n 屏蔽默认输出-r 支持扩展正则-i 修改源文件条件:行号  4    4;5  4,5   4,+10  4~2(第4行和后面步长为2的行)sed -n '2~2P' sed.txt  偶数行sed -n '1~2P' sed.txt  奇数行  sed  -n '$=' a.txt            //输出文件的行数/正则/sed  -n 'p' a.txt            //输出所有行,等同于cat a.txtsed  -n '4p' a.txt            //输出第4行sed  -n '4,7p' a.txt        //输出第4~7行sed  -n '4,+10p' a.txt        //输出第4行及其后的10行内容sed  -n '/^bin/p' a.txt        //输出以bin开头的行sed  '/xml/!d' a.txt         //删除不包含xml的行,!符号表示取反sed  '$d' a.txt                //删除文件的最后一行sed  '/^$/d' a.txt             //删除所有空行tips:   sed 's/xml//g'     a.txt     //将所有的xml都删除(替换为空串)sed -n 's/2017/xxxx/gp' sed.txt //替换所有并打印sed 's/xml/XML/'  a.txt        //将每行中第一个xml替换为XMLsed 's/xml/XML/3' a.txt     //将每行中的第3个xml替换为XMLsed 's/xml/XML/g' a.txt     //将所有的xml都替换为XMLsed 's/xml//g'     a.txt     //将所有的xml都删除(替换为空串)sed 's#/bin/bash#/sbin/sh#' a.txt  //将/bin/bash替换为/sbin/sh (涉及到路径时用其他符合分隔)sed '4,7s/^/#/'   a.txt         //将第4~7行注释掉(行首加#号)sed 's/^#an/an/'  a.txt         //解除以#an开头的行的注释(去除行首的#号)sed -n 's/.//2;s/.$//p' sed.txt 删除文件中每行的第二个、最后一个字互换:(后向引用)sed -rn 's/^(.)(.*)(.)$/\3\2\1/p' sed.txt 第一个、倒数第1个字符互换sed -rn 's/^(.)(.)(.*)(.)(.)$/\1\4\3\2\5/p' sed.txt  第二第四互换注意:做对换时空格也算如果测试文件中首尾都是空格的话看不出效果首为R 尾为空格视觉效果是把R放到最后去了。sed 's/[0-9]//' nssw.txt        删除文件中所有的数字sed -r 's/[0-9]//g;s/^( )+//' nssw2.txt 删除所有数字、行首空格sed -rn 's/([A-Z])/[\1]/gp' nssw.txt    为文件中每个大写字母添加括号sed -rn 's/([a-Z0-9])/[\1]/gp' sed.txt  为文件中每个字母和数字添加括号sed -rn 's/([a-Z0-9 ])/(\1)/gp' sed.txt 为文件中每个字母和数字空格添加括号sed 导入导出操作:r动作与i选项配合才会存入,否则只会输出读取文件: 3r b.txt  4,7r  b.txt         第3行下方插入b;第 4-7行每行下插入bw动作以覆盖的方式另存为新文件另存为文件:3w c.txt  4,7w  c.tx     将第三行另存为;将第4-7行另存为sed复制粘贴:模式空间:存放当前处理的行  若当前处理行不符合处理条件则原样输出 处理完当前行再读入下一行来处理保持空间:左右类似剪贴板默认存放一个空行(换行符\n :回车)h               模式空间——》覆盖———》保持空间           复制H               模式空间——》追加———》保持空间           复制g               模式空间——》覆盖———》保持空间            粘贴G               模式空间——》追加———》保持空间           粘贴sed '3h;3d;5g;'    sed.txtsed '3h;3d;5G'     sed.txtsed '3g'     sed.txt  第三行变空格。指令:p 打印d 删除s 替换s/旧/新/ga 指定行之后追加    sed  '2a XX'   a.txt            //在第二行后面,追加XXi 指定行之前插入sed  '2i XX'   a.txt            //在第二行前面,插入XXc 替换行sed  '2c XX'   a.txt            //将第二行替换为XXsed  '1c mysvr.tarena.com' /etc/hostname    修改主机名脚本中修改配置文件时:cp /etc/vsftpd/vsftpd.conf{,.bak}  给配置文件备份/etc/hosts  这个文件非常有用:优先级比dns高 本地解析库sed  -i  '$a 192.168.4.20  D  '  /etc/hosts这样就可以ssh D 直接远程这个ip了。sed  -i  '$a 192.168.4.20  www.baidu.com '  /etc/hosts这样访问百度就快些了不用去找dns解析了 

文本处理三剑客awk:

    awk [选项] '[条件]{指令}' 文件      多条编辑指令,可用分号分隔默认将空格、制表符等作为分隔符             (cut sort 也是是默认空格Tab)grep sed 不能直接打印某列要结合字符串的截取工具使用-F 可指定分隔符  识别多种单个的字符   awk -F [:/] '{print $1,$10}' /etc/passwdawk常用内置变量:$0 文本当前行的全部内容$1  文本的第1列$3  文件的第3列,依此类推NR  文件当前行的行号NF  文件当前行的列数(有几列awk -F: '{print NR,NF}' passwd.txtawk -F: '{print NR,$NF}' /etc/passwd  永远打印最后一行!awk -F: '{print NR,$NR}' /etc/passwd  第几行的时候就打印第几列!可以打印常量:awk -F: '{print $1,"的解释器:",$7}' /etc/passwd     打印常量必须要加双引号, 加逗号有空格,不加逗号无空格!案例: free |awk '/Mem/{print $NF}'    查看目前可用内存ifconfig eth0 | awk '/RX p/{print $5}'  查看接收流量!ifconfig eth0 | awk '/TX p/{print $5}'  查看发送流量!df -h | awk '/\/$/{print $4}' #:\/$代表对/转义!!看跟分区可用空间。df  | awk '/\/$/{print $4}'  故意不加单位 在脚本中好当成数值比较!!!df -h / | tail -1 | awk '{print $4}' 第一个/ 代表要看/(根)的情况 提取最后一行 给awk在网页中查看脚本:远程监控服务器网卡 内存等等情况(相当于动态页面了)rpm -qa | grep httpdcp /root/share/test5-19-1.sh /var/www/cgi-bin/test5-19-1.html   必须放在脚本专用目录下chmod +x /var/www/cgi-bin/test5-19-1.html   必须要加X不然访问不了要报404. 看到404就检查有没有Xsystemctl stop firewalldsetenforce 0 ip/cgi-bin/test5-19-1.html   访问验证!!!tips:要想使访问时换行显示,要在/var/www/cgi-bin/test5-19-1.html 给这个文件加<br>然后再重启服务!!而不是改之前的脚本文件,思路一定要清晰啊小伙子。tips:如果cp -P test5-19-1.html /var/www/html/http://192.168.4.20/test5-19-1.html访问到的就不是脚本执行的结果了,就是html 代码执行的结果了。如下#!/bin/bash echo "Content-type: text/html" echo "" ifconfig eth0 | awk '/netmask/{print "Ip:"$2}' echo "" ifconfig eth0 | awk '/RX p/{print "接收流量:"$5}' echo "" ifconfig eth0 | awk '/TX p/{print "发送流量:"$5}' echo "" df | awk '/\/$/{print "根分区可用:"$4}' echo "" free |awk '/Mem/{print "内存可用:"$NF}'路径一定要是/var/www/cgi-bin/test5-19-1.html 才能访问到脚步执行结果。(在未修改配置文件前提下)格式化输出:awk处理的时机:处理第一行之前做准备工作    只做预处理的时候,可以没有操作文件awk 'BEGIN{print x+1}'           #x可以不定义,直接用,默认值位0中间进行逐行处理处理完最后一行做总结awk  [选项]  ' BEGIN{指令} {指令} END{指令}'  文件BEGIN{ }    行前处理,读取文件内容前执行,指令执行1次{ }     逐行处理,读取文件过程中执行,指令执行n次END{ }      行后处理,读取文件结束后执行,指令执行1次统计系统中使用bash作为登录Shell的用户总个数awk 'BEGIN{x=0}/bash$/{x++} END{print x}' /etc/passwdawk '/bash$/{x++} END{print x}' /etc/passwd  与上条命令等效 x未定义默认为0格式化输出/etc/passwd    awk -F: 'BEGIN{print "User\tUID\tHome"} \{print $1 "\t"  $3  "\t"  $6}     \     使用“\t”显示Tab制表位END{print "Total",NR,"lines."}' /etc/passwdawk -F: 'BEGIN{print "用户名   家目录   UID"} {print $1,$6,$3 x++} END{print "总共"x"行"}' /etc/passwdawk -F: 'BEGIN{print "用户名","家目录","UID"} {print $1,$6,$3} END{print "总共"NR"行"}' /etc/passwdawk -F: 'BEGIN{print "用户名","家目录","UID"} {print $1,$6,$3 x++} END{print "总用户量:"x }' /etc/passwdEND{print "总共"NR"行"}  END{print "总共"x"行"}  打印最后的时候:注意变量不要引号,常量要引号,这是个坑啊!!!      awk -F: 'BEGIN{print "用户名\t家目录\tUID"} {print $1"\t"$6"\t"$3 x++}END{print "总用户量:"x }' /etc/passwd | column -tcolumn -t 自动排版对齐!!!awk -F: '{print $1,$2,$3 }' /etc/passwd | column -tawk处理条件:正则awk -F: '/bash$/{print}' /etc/passwdawk -F: '$1~/(zhangsan|root)/{print $7}' /etc/passwd  (支持扩展的正则)~代表匹配:$1匹配后面的正则。并且是包含就算,模糊匹配 #第一列包含root或zhangsan的打印第7列。[root@D share]# awk -F: '$1~/^root/' /etc/passwdroot:x:0:0:root:/root:/bin/bashroota:x:1004:1024::/home/roota:/bin/bash    模糊匹配awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd    !~不匹配使用数值/字符串比较设置条件比较符号:== != > >= < <=awk -F: '$1=="root"' /etc/passwd   常量要引号  精确匹配用户是为root的 不包含aroot root arootb 等等。    awk -F: 'NR==3'   打印第三行 不写{指令}默认为打印整行(所有列)awk -F: '$3>=1000' /etc/passwd  大于等于1000的都是普通用户。    awk -F: '$3>10  && $3<5'  /etc/passwd  tips:带逻辑判断的 要写合理  不然的话不会报错但是脚本执行结果不对,就不好排错了。seq 100 | awk '$1%6!=0'  不能被6整除的。逻辑测试条件      seq 100 | awk '$1%6==0 && $1%5==0'      5和6的公倍数。seq 100 | awk '$1%7==0 || $1~/7/'   7整除或者包含7awk '/Failed/ && /invalid/' /var/log/secure  数学运算awk 'BEGIN{a++;print a}'  1     case:   [root@svr5 ~]# cat getupwd-awk.sh#/bin/bashA=$(awk -F:  '/bash$/{print $1}' /etc/passwd)        ## 提取符合条件的账号记录for i in $Adogrep $i /etc/shadow | awk -F: '{print $1,"-->",$2}'                doneawk 命令内部不能直接调用shell中的外部变量 $1==$i 要用-v选项来重新定义调用 很麻烦。awk流程控制(if,for,while)if判断:单分支:if(判断){命令}      #第一个{表示命令开始    第二个}代表命令结束多分支:if(判断){命令}else{命令}      #所有指令都要放在{}里!!!!awk -F: '{if($3<=1000) {i++}} END{print i} ' /etc/passwd   #结构很重要哈!!不行就先把结构框架打出来再往里面添加数据!!awk -F: '{if($3<=1000){x++}else{y++}} END{print x,y}' /etc/passwd  for循环:awk数组:awk 'BEGIN{a++;print a}'  1         未定义的变量对它++就是1!!!!a=a+1 a未出现过,为空 空+1=1awk 'BEGIN{a[0]++;print a[0]}'非常重要:awk 'BEGIN{a[0]=00;a[1]=11;a[2]=22; for(i in a){print i,a[i]}}' 0 01 112 22结果证明:i取值不是a的值而是a的下标。a[i]才是数组a的值。awk数组的下标除了可以使用数字,也可以使用字符串,字符串需要使用双引号:awk 'BEGIN{a["192.168.4.254"]=11;print a["192.168.4.254"]}'  11awk 'BEGIN{a[192.168.4.254]=11;print a[192.168.4.254]}'  11案例:        背景:awk 统计每一个ip的访问次数来进行过滤ls  -lh /var/log/httpd/access_log   8.5kwc -l /var/log/httpd/access_log     31行ab -c 100 -n 100000 http://192.168.4.20/    dos***:模拟100人访问了网站10万次,这时刷新页面就会很卡。tips:如果下标是变量就不能用引号;会把它当字符串的!先不加,结果不对了再加这样就不会错了.awk '{IP["$1"]++}END{for (i in IP) {print IP[i],i}}' /var/log/httpd/access_log 63445 $1awk '{IP[$1]++}END{for (i in IP) {print IP[i],i}}' /var/log/httpd/access_log |sort -n 从小到大排序219 ::163226 192.168.4.254 

awk脚本应用案例:

        案例:快速进行源码包安装yum repolist | awk '/repolist/ {print $2}' |sed 's/,//g'源码包装的软件不能用systemctl restart (enable) 来进行管理。netstat -ntulp |grep httpdtcp6       0      0 :::80                   :::*                    LISTEN      8002/httpdnetstat -ntulp |grep :80        tcp6       0      0 :::80                   :::*                    LISTEN      8002/httpdnetstat -ntulp |grep :80[ $? -ne 0 ]  && /usr/local/nginx/sbin/nginxa=$(netstat -ntulp |awk '/:80/{print $7}'|cut -d/ -f2)[ $a == "httpd" ] && systemctl stop $a  b=(netstat -ntulp |awk '/:80/{print $7}'|cut -d/ -f2|cut -d: -f1)启动脚本niginx(case)看本机状态信息uptime |awk '{print$9,$10,$11}ifconfig eth0 | awk '/RX p/{print $5}'ifconfig eth0 | awk '/TX p/{print $5}'free |awk '/Mem/{print $NF}'df | awk '/\/$/{print $4}'cat /etc/passwd |wc -lwho |wc -lrpm -qa |wc -l$!最后一个后台进程的进程号。   防止远程ssh暴力破解密码awk '/Failed/ && /invalid/{print $13}' /var/log/secure |awk '{a[$1]++}END{for (i in a){print i,a[i]}}'awk '/Failed/ && $9!~/invalid/{print $11}' /var/log/secure |awk '{a[$1]++}END{for (i in a){print i,a[i]}}'1 #!/bin/bash2 a=$(awk '/Failed/ && $9!~/invalid/{print $11}' /var/log/secure |awk '{a[$1]++}END{for (i in a){print i,a[i]}}'|awk '{if($2>5){print$1}}')3 4 b=$(awk '/Failed/ && $9!~/invalid/{print $11}' /var/log/secure |awk '{a[$1]++}END{for (i in a){print i,a[i]}}'|awk '{if($2>5){print$1}}')5 echo $a6 echo $b

转载于:https://blog.51cto.com/13659481/2120840

Linux阶段总结shell脚本相关推荐

  1. Linux 中启用 Shell 脚本的调试模式

    shell 脚本调试系列 Linux 中启用 Shell 脚本的调试模式 在 Shell 脚本中执行语法检查调试模式 在 Shell 脚本中跟踪调试命令的执行 概述 脚本是存储在一个文件的一系列命令. ...

  2. 如何在 Linux 中启用 Shell 脚本的调试模式

    脚本是存储在一个文件的一系列命令.在终端上输入一个个命令,按顺序执行的方法太弱了,使用脚本,系统中的用户可以在一个文件中存储所有命令,反复调用该文件多次重新执行命令. 在学习脚本或写脚本的初期阶段,我 ...

  3. 大神教你如何在 Linux 中启用 Shell 脚本的调试模式

    导读 脚本是存储在一个文件的一系列命令.在终端上输入一个个命令,按顺序执行的方法太弱了,使用脚本,系统中的用户可以在一个文件中存储所有命令,反复调用该文件多次重新执行命令. 在学习脚本或写脚本的初期阶 ...

  4. Linux中执行shell脚本的4种方法

    这篇文章主要介绍了Linux中执行shell脚本的4种方法总结,即在Linux中运行shell脚本的4种方法,需要的朋友可以参考下. bash shell 脚本的方法有多种,现在作个小结.假设我们编写 ...

  5. Linux下的shell脚本实战之用户创建

    Linux下的shell脚本实战之用户创建 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 二.脚本内容 三.运行脚本 一.脚本要求 1.该脚本提示用户创建用户名和密码 2.判断输入的用户名是 ...

  6. linux下执行shell脚本文件,Linux下使用shell脚本自动执行脚本文件

    搜索热词 以下实例本人在Centos6.5 64位操作系统中使用 一.定时复制文件 a.在/usr/local/wfjb_web_back目录下创建 tomcatBack.sh文件 #将tomcat中 ...

  7. Linux 定时执行shell 脚本

    2019年第 85 篇文章,总第 109 篇文章 本文大约2000字,阅读大约需要6分钟 crontab 可以在指定的时间执行一个shell脚本以及执行一系列 Linux 命令. 定时执行shell ...

  8. linux 定时执行搅拌,Linux上定时shell脚本

    本文主要介绍在Linux系统上部署定时器,定时执行shell脚本,通过脚本执行sql文件 sql文件 -- 创建表 create table if not exists iot_test.iot_ta ...

  9. Linux中执行shell脚本的5种方法总结

    Linux中执行shell脚本的4种方法总结,即在Linux中运行shell脚本的4种方法: 方法一:切换到shell脚本所在的目录(此时,称为工作目录)执行shell脚本: 复制代码 代码如下: c ...

最新文章

  1. AttributeError: module librosa has no attribute output No module named numba.decorators错误解决
  2. php 中调用 require include 的比较
  3. mavne的依赖、继承、聚合
  4. 婧婧音乐开发笔记01篇-项目组织结构和布局文件
  5. mysql中的rman备份_oracle数据库 rman基本备份操作
  6. java xml文件无法打开,java – 无法打开beans.xml(配置文件)因为不存在
  7. 详解基于J2ME平台下SOAP协议的应用
  8. R语言——RStudio下载R包时总是下载不成功?解决方案
  9. 百度地图infowindow上添加自定义点击事件
  10. 加州理工学院计算机研究生申请条件,加州理工学院研究生申请条件
  11. 漫漫Java学习路,第十四天
  12. 团队的英文翻译缩写_有感情的一起游戏的团队英文缩写
  13. 如何正确学习和使用设计模式
  14. docker方式运行SRS
  15. 捕鱼游戏源码(数值+完整项目资源)
  16. python的占位符%d %i %.nf %s
  17. 2021年“深育杯“网络安全大赛Writeup
  18. SQL三值逻辑和NULL
  19. 【算法系列专栏介绍】
  20. mount 命令介绍

热门文章

  1. html缓存特效代码,HTML特效代码
  2. 类型多种_五轴机床有很多种类型,你知道几种?
  3. getRunningTasks和getRunningAppProcesses失效
  4. setDrawingCacheEnabled(boolean flag)
  5. 广汽研究院BMS软件工程师_八大高手齐聚CATIA决赛,3人获“广汽技术创新能手”...
  6. python2异步编程_python异步编程 (转载)
  7. java实现文件名过滤器接口_Java使用文件过滤器FileFilter、FilenameFilter搜索文件
  8. java float x=26f_东软java笔试题
  9. midi api java_Java声音api – 扫描MIDI设备
  10. mysql中如何求字段的个数字_求高手帮小弟解决一下!关于mysql字段中数字提取求和的问题?...