shell编程由浅入深奋斗史

2.vi/vim编辑器的熟练使用。SSH客户端软件的设置。

3.基础的服务,系统服务ntpcrond,网络服务nfsrsyncinotifysersyncsshlamplnmp

Shell是一个命令解释器,是linux/unix操作系统的最外层,负责直接与用户对话,把用户输入的命令解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕给用户。

3.什么是shell脚本?

当命令或者语句不在命令行执行,而是通过一个程序文件执行时,该程序或文件就被成为shell脚本或者shell程序,shell程序类似DOS系统下的批处理程序。

4.简单的例子

[root@yangjianboinbeijingday1]#catdel_messages.shcd/var/logcat/dev/null>messagesecho"messagesisnull!"这个脚本的缺点:缺乏基本的逻辑判断,会导致前面的命令出错后,后面的命令无法正确执行。

上面脚本的升级版:

#!/bin/bash#清除messages日志脚本,版本2--yangjianboLOG_DIR=/var/logROOT_UID=0if["$UID"-ne"$ROOT_UID"]thenecho"Youmustberoot."exit1ficd$LOG_DIR||{echo"pleasechangeto/var/log/">&2exit1}cat/dev/null>messages&&echo"messagesiscleanedup"exit03.Shell程序在运维工作中的作用和地位Shell脚本很擅长处理纯文本类型的数据,而linux中几乎所有的配置文件和日志文件都是纯文本类型的文件。

贴近系统层的操作,shell是最佳的。shell的伙伴(2000个linux命令,awk,sed,grep)

1.主要分为两大类

Bourneshell

Cshell

2.高级运维或者开发型运维常用的脚本语言

php

perl

python

Linuxbash

Solaris和FreeBSDsh

AIXksh

HP-UXsh

如何查看系统的默认shell

查看系统的shell版本

bash--version

1.shell脚本组成:Unix/linux命令bashshell命令注释程序结构控制语句

第一行指出是由哪个解释器来执行。

#!/bin/bash或者#!/bin/sh

#!/bin/awk

#!/bin/sed

注释:使用的是#

1.方法

第一种:当脚本本身没有执行权限,使用bash脚本或者sh脚本。文件权限没有x

/bin/bash1.sh

bash1.sh

sh1.sh

第二种:需要脚本有权限,使用./脚本名执行或者全路径。文件权限必须得有x

./1.sh

第三种:sourcescript-name或者.script-name

第三种与第一种和第二种的区别:

举例来说明:

面试题:cattest.shuser=`whoami`shtest.shecho$user结果是什么?结果为空,这是为什么呢?当使用第一种方法和第二种方法执行sh文件,系统会给一个新的bash执行让我们执行sh里面的命令,因此变量都是子进程的bash中执行的。当sh执行完毕后,子进程bash内的所有数据被删除,因此为空。但是使用第三种方法就不一样了,因为是在自己的进程中执行sh,不会产生子进程,所以不会为空。8.Shell脚本开发规范和习惯1.开头指定脚本解释器

3.脚本中不用中文注释

4.脚本以.sh为扩展名

5.代码书写的优秀习惯

成对出现的符号一次性写完。

for循环要一次写完。

if语句要一次性写完。

通过手工缩进让代码更容易读。让代码有层次感。

1.分类:环境变量和局部变量

环境变量也称为全局变量,可以在创建它们的shell及其派生出来的任意子进程shell中使用。

局部变量只能在它们自己的shell中或脚本中使用。

2.环境变量

环境变量可以在命令行设置,但是注销就消失,所以需要在用户的家目录.bash_profile或者全局配置/etc/profile或者/etc/profile.d/中定义。

环境变量均为大写,必须用export导出。

3.环境变量读取配置文件,分为两种情况。

1.loginshell

3.su-username

2.non-loginshell

1.suusername

2.图形界面下打开的终端

3.执行脚本

4.通过ssh免密钥的方式,直接执行命令。

sshjava@192.168.1.100'echo$TESTZZ'注意在命令行使用单引号,脚本使用双引号

3.配置文件分类

1.按生效范围划分

1.全局

/etc/profile

/etc/bashrc

/etc/profile.d/*.sh

2.个人

~/.bash_profile

~/.bashrc

2.按功能划分

用途:定义环境变量

运行命令或脚本

全局:/etc/profile

个人:~/.bash_profile

用途:定义命令别名

定义本地变量

全局:/etc/bashrc

个人:~/.bashrc

/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc

~/.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh

4.查看环境变量

env:列出所有的环境变量

set:查看所有变量(含环境变量与自定义变量)

export:自定义变量转成环境变量

1.显示echo$LANG

2.env命令

3.set命令

4.取消环境变量

unset变量名

1.本地变量

1.定义:本地变量在用户当前shell生存期的脚本中使用。退出或者进入另外一个进程,就会失效。

2.变量定义:

例子1:

[root@yangjianboinbeijingday1]#a=192.168.1.2[root@yangjianboinbeijingday1]#b='192.168.1.2'[root@yangjianboinbeijingday1]#c="192.168.1.2"[root@yangjianboinbeijingday1]#echo"a=$a""b=$b""c=${c}"a=192.168.1.2b=192.168.1.2c=192.168.1.2例子2:

3.变量的命名规范

1.都使用大写

2.不能以数字开头

3.等号两边不能直接有空格,如果需要使用空格,需要加引号。

4.把命令作为变量

需要使用反引号。

也可以使用$()

批量创建目录mkdir`seq5`mkdir$(echo{a..e})mkdir{o..w}5.关于awk引用shell变量的使用情况

1.位置变量

$0获取当前执行的shell脚本的文件名,包括路径。

[root@yangjianboinbeijingday1]#cat0.sh#!/bin/bashecho$0[root@yangjianboinbeijingday1]#sh0.sh#取文件名0.sh[root@yangjianboinbeijingday1]#sh/server/scripts/day1/0.sh#取完整路径和文件名/server/scripts/day1/0.sh[root@yangjianboinbeijingday1]#cat0.sh#!/bin/bashdirname$0从$0中取路径basename$0从$0中取文件名[root@yangjianboinbeijingday1]#sh/server/scripts/day1/0.sh/server/scripts/day10.sh

想单独获得路径和文件名

dirname/server/scripts/0.sh

basename/server/scripts/0.sh

$n获取当前执行的shell脚本的第n个参数值,当n大于9,用大括号括起来${10}。

[root@yangjianboinbeijingday1]#catn.sh#!/bin/bashecho$1$2$3${10}[root@yangjianboinbeijingday1]#bashn.sh{1..11}12310[root@yangjianboinbeijingday1]#bashn.sh`seq11`12310$#获取当前执行的shell脚本的传入的参数个数。

[root@yangjianboinbeijingday1]#catn.sh#!/bin/bashecho$1$2$3${10}echo$#[root@yangjianboinbeijingday1]#shn.sh12341234[root@mysql-37scripts]#/bin/bashcanshu.sh{a..z}传入的参数个数为26,但实际接收的参数个数位为4abcd26

用于判断shell脚本参数个数的时候。实战例子:[root@yangjianboinbeijingday1]#catbijiao.sh#!/bin/bashif[$#-ne3];thenecho"pleaseinput3args!"elseecho"inputOK"fi[root@yangjianboinbeijingday1]#shbijiao.shpleaseinput3args![root@yangjianboinbeijingday1]#shbijiao.sh1pleaseinput3args![root@yangjianboinbeijingday1]#shbijiao.sh12pleaseinput3args![root@yangjianboinbeijingday1]#shbijiao.sh123inputOK[root@yangjianboinbeijingday1]#shbijiao.sh1234pleaseinput3args!

$*获取当前shell传入的所有的参数

#!/bin/bashuser=`whoami`echo$*[zhangshaohua1510@mysql-37scripts]$/bin/bashtest.sh123123

$@获取当前shell所有传参的参数

#!/bin/bashuser=`whoami`echo$@[zhangshaohua1510@mysql-37scripts]$/bin/bashtest.sh123123$*与$@的区别在于,如果不加双引号,那么它们的结果是一样;如果加上双引号,$*输出的结果是"$1$2$3",而$@输出的结果是"$1","$2","$3"。

不带引号的结果:

#!/bin/bashecho$*foriin$*;doecho$idoneecho$@foriin$@;doecho$idoneshtest.sh"Iam"yangjianbo不带双引号的时候,两个输出的结果是一样的。Iamyangjianbo这是$*IamyangjianboIamyangjianbo这是$@Iamyangjianbo带双引号的结果:

#!/bin/bashecho$*foriin"$*";doecho$idoneecho$@foriin"$@";doecho$idoneshtest.sh"Iam"yangjianbo带双引号的时候,$*与$@的结果完全不一样。Iamyangjianbo这是$*Iamyangjianbo$*带引号以后,把$1$2$3当做一个整体,输出了。Iamyangjianbo这是$@Iam$@带引号以后,把参数一个一个输出了。yangjianbo

1.$:获取上一个指令的返回值(0为成功,非零为失败)

0成功

2权限拒绝

1~125运行失败,脚本命令,系统命令错误或参数传递错误

126找到该命令了,但是无法执行

127未找到要运行的命令

>128命令被系统强制结束

[root@mysql-37scripts]#catfanhui.sh#!/bin/bashif[$#-ne2];thenecho"USAGE:$0mustbetwoargs."exit119elseechoyangianbofi[root@mysql-37scripts]#/bin/bash/server/scripts/fanhui.shUSAGE:/server/scripts/fanhui.shmustbetwoargs.[root@mysql-37scripts]#echo$119

[root@mysql-37scripts]#/bin/bash/server/scripts/fanhui.sh12yangianbo$返回值的用法如下:

1.判断命令或脚本或函数等程序是否执行成功。

2.若在脚本中调用执行"exit数字",则会返回这个数字给"$"变量。

3.如果是在函数里,则通过"return数字"把这个数字以函数返回值的形式传给"$"。

2.$$:获取当前执行的shell脚本的进程号

#!/bin/bashuser=`whoami`echo$$[zhangshaohua1510@mysql-37scripts]$/bin/bashtest.sh117683.$_:获取上一条命令的最后一个参数值

[root@192tmp]#shtest.sh"Iam"yangjianboIamyangjianboIamyangjianboIamyangjianboIamyangjianbo[root@192tmp]#echo$_bo4.$!:获取上一次执行脚本的pid

1.echo在屏幕上输出信息

语法:echoargs#后面跟字符串或者变量

-n:不换行输出

-e:解析转义字符

常用的转义字符:

\n:换行

\r:回车

\t:制表符

\b:退格

\v:纵向制表符

[root@mysql-37scripts]#echo"yangjianbo";echo"liudehua"默认自动换行yangjianboliudehua[root@mysql-37scripts]#echo-n"yangjianbo";echo"liudehua"-n不换行yangjianboliudehua[root@mysql-37scripts]#echo-e"yangjianbo\nliudehua"\n换行yangjianboliudehua[root@mysql-37scripts]#echo-e"yangjianbo\tliudehua"\t制表符tabyangjianboliudehua[root@mysql-37scripts]#echo-e"yangjianbo\bliudehua"\b退格,可以看到少了一个oyangjianbliudehua[root@mysql-37scripts]#echo-e"yangjianbo\vliudehua"\v纵向制表符yangjianboliudehua2.eval执行到eval语句,shell读取参数,并将他们组成一个新的命令

#!/bin/bashecho\$$#输出的结果为$2[sysadmin@192tmp]$sudo/bin/bashtest.shyangjianboliudehua$2#!/bin/basheval"echo\$$#"eval重新组合了echo$2,所以可以输出liudehua[sysadmin@192tmp]$sudo/bin/bashtest.shyangjianboliudehualiudehua3.exec在不创建新的进程的情况,执行指定的命令,执行完以后,该进程也就结束了。

[sysadmin@192tmp]$execdate2021年10月26日星期二11:22:10CST执行完以后,直接退出注销了。4.read标准输入,传给指定变量

[root@yangjianboinbeijingday2]#catread.shread-p"pleaseinputyourname:"usernameecho$username[root@yangjianboinbeijingday2]#shread.shpleaseinputyourname:yangjianboyangjianbo5.history查看历史记录

6.printf格式化打印

7.ulimit文件系统与程序的限制

8.shift位置参数偏移量,每执行一次,向左移动一个位置

[root@yangjianboinbeijingday2]#set--"Iam"handsomeoldboy.[root@yangjianboinbeijingday2]#echo$#3[root@yangjianboinbeijingday2]#echo$1Iam[root@yangjianboinbeijingday2]#echo$2handsome[root@yangjianboinbeijingday2]#echo$3oldboy.[root@yangjianboinbeijingday2]#shift[root@yangjianboinbeijingday2]#echo$1handsome[root@yangjianboinbeijingday2]#echo$2oldboy.[root@yangjianboinbeijingday2]#echo$3[root@yangjianboinbeijingday2]#echo$0-bash9.exit退出shell

1.返回变量的内容

[root@yangjianboinbeijingday2]#OLDBOY="Iamoldboy"[root@yangjianboinbeijingday2]#echo$OLDBOYIamoldboy[root@mysql-37scripts]#echo${OLDBOY}Iamoldboy2.返回变量值的长度

[root@yangjianboinbeijingday2]#echo${#OLDBOY}113.截取变量值

[root@yangjianboinbeijingday2]#echo${OLDBOY:2}从索引为2的开始截取,包含2amoldboy[root@yangjianboinbeijingday2]#echo${OLDBOY:3}从索引为3的开始截取,包含3moldboy3.截取其中固定的变量值,第一个参数为索引值,第二个为步长

[root@yangjianboinbeijingday2]#echo${OLDBOY:5:2}从索引为5的开始截取,截取2个长度ol4.从开头删除匹配的子字符串###

[root@mysql-37scripts]#OLDBOY="abcABC123ABCabc"[root@mysql-37scripts]#echo$OLDBOYabcABC123ABCabc[root@mysql-37scripts]#echo${OLDBOY#a*c}从头开始删除最短匹配a*c的字符串ABC123ABCabc[root@mysql-37scripts]#echo${OLDBOY##a*c}从头开始删除最长匹配a*c的字符串,所以整个都删掉了

5.从字符串的结尾开始删除%%%

[root@mysql-37scripts]#echo${OLDBOY}abcABC123ABCabc[root@mysql-37scripts]#echo${OLDBOY%a*c}从尾部开始删除最短匹配的a*cabcABC123ABC[root@mysql-37scripts]#echo${OLDBOY%%a*c}从尾部开始删除最长匹配的a*c,所以整个都删掉了6.字符串替换

语法:${变量名/子字符串/替换以后的字符串}从头开始查找子字符串进行替换,替换第一个

[root@yangjianboinbeijingday2]#echo$OLDBOYIamoldboyam[root@yangjianboinbeijingday2]#echo${OLDBOY/I/is}isamoldboyam语法:${变量名//子字符串/替换以后的字符串}替换匹配的所有字符串

[root@yangjianboinbeijingday2]#echo${OLDBOY//am/is}isisoldboyis7.生产实例

1.批量删除文件名称中的固定字符串。

[root@yangjianboinbeijingday2]#virename.sh#!/bin/bashBASEDIR=/server/scripts/day2/testdirif[-d$BASEDIR];thencd$BASEDIRforfilein`ls*.bak`;domv$file${file//_20190910/}.bak;替换为空donefi2.修改文件的扩展大写变小写,从结尾开始匹配

forfilein`ls*.HTML`;domv$file${file//HTML/html};done3.把文件名修改为大写。

ls*_20180405.bak|awk-F"_20180405"'{print"mv"$0,$1$2}'|bash4.使用rename命令修改。

rename"_20180405"""*.bakrename"HTML""html"*.HTML16.bash变量子串的深入介绍与系统案例分析1.${value:-word}

当变量未定义或者值为空,返回值为word的内容,否则返回变量的值。这个功能用来判断变量是否已定义。如果没有定义,就返回word,定义了就返回定义的值。

[root@yangjianboinbeijingtestdir]#result=${test:-word}[root@yangjianboinbeijingtestdir]#echo$test[root@yangjianboinbeijingtestdir]#echo$resultword2.${value:=word}

当变量未定义或者值为空,返回word的值的同时将word值赋给value.这个变量的功能可以解决变量没有定义的问题,并确保没有定义的变量始终有值。

[root@yangjianboinbeijingtestdir]#result=${test:=word}[root@yangjianboinbeijingtestdir]#echo$test之前test的值是空的,但是现在已经被赋值word了,这就是与-word的区别word[root@yangjianboinbeijingtestdir]#echo$resultword3.${value:"word"}

当变量未定义或者值为空,返回word,否则返回定义的值。这个功能用来设定由于变量未定义而报错的具体内容。

[root@yangjianboinbeijingtestdir]#result=${test:word}-bash:test:word[root@yangjianboinbeijingtestdir]#result=${test:"notdefined"}-bash:test:notdefined4.${value:+word}

测试变量是不是存在。如果返回了值,那么说明变量被定义了。否则就是变量没有定义。

[zhangshaohua1510@mysql-37~]$oldboy=${oldgirl:+yangjianbo}[zhangshaohua1510@mysql-37~]$echo$oldboyolboy值为空[zhangshaohua1510@mysql-37~]$echo$oldgirloldgirl值为空[zhangshaohua1510@mysql-37~]$oldgirl=20[zhangshaohua1510@mysql-37~]$oldboy=${oldgirl:+yangjianbo}定义了oldgirl,则oldboy返回,后面的yangjianbo[zhangshaohua1510@mysql-37~]$echo$oldboyyangjianbo[zhangshaohua1510@mysql-37~]$echo$oldgirl205.生产实例

[root@mysql-37scripts]#catdel20190910.sh#!/bin/bashfind${path-/tmp}-name"*.tar.gz"-typef-mtime+7|xargsrm-rf{}#没有定义path,那么就使用/tmp作为路径17.变量的数值计算常用的算术运算符

常用的算术运算命令

1.(())常用,效率最高,只适合整数

1.简单运算

[root@mysql-37scripts]#((a=1+1))[root@mysql-37scripts]#echo$a2[root@mysql-37scripts]#echo$((5*9))45

2.复杂运算

[root@mysql-37scripts]#echo$((100*(100+1)/2))50503.利用双括号进行比较判断

[root@mysql-37scripts]#echo$((3>8))0[root@mysql-37scripts]#echo$((3<8))1[root@mysql-37scripts]#if((8<3))>then>echo1>else>echo0>fi04.在变量前后使用--和++特殊运算符的表达式

赋值操作[root@yangjianboinbeijingsystemd]#echo$((a+=10))10

增长减少操作[root@yangjianboinbeijingsystemd]#a=1[root@yangjianboinbeijingsystemd]#echo$((a++))1[root@yangjianboinbeijingsystemd]#echo$((a++))2[root@yangjianboinbeijingsystemd]#echo$((a++))3[root@yangjianboinbeijingsystemd]#echo$((a++))4

注意:a++与++a的区别,a++先赋值再运算,++a先运算再赋值

从1加到100的和是多少?

[root@yangjianboinbeijingsystemd]#echo$((100*(100+1)/2))5050

使用命令行的方式,实现一个加减乘除的计算器。

[root@yangjianboinbeijingday2]#vi02.shecho$(($1))

[root@yangjianboinbeijingday2]#cat03.shecho$(($1$2$3))[root@yangjianboinbeijingday2]#sh03.sh1212[root@yangjianboinbeijingday2]#sh03.sh1+23[root@yangjianboinbeijingday2]#sh03.sh1+34[root@yangjianboinbeijingday2]#sh03.sh1+23[root@yangjianboinbeijingday2]#sh03.sh1+2+53[root@yangjianboinbeijingday2]#sh03.sh1+2+811

2.let命令这是shell的内置命令

实际操作:

[root@yangjianboinbeijingday2]#i=2[root@yangjianboinbeijingday2]#leti=i+8[root@yangjianboinbeijingday2]#echo$i10注意:如果去掉let,相当于给i赋值:i+83.expr命令

用于整数计算

[root@yangjianboinbeijingday2]#expr2+22+2[root@yangjianboinbeijingday2]#expr2+24[root@yangjianboinbeijingday2]#expr2*2expr:语法错误[root@yangjianboinbeijingday2]#expr2\*24注意:运算符左右都需要有空格,乘号要使用\进行转义。[root@yangjianboinbeijingday2]#expr$i+57

[root@yangjianboinbeijingday2]#expr$[2+8]10

expr可以统计字符串的长度

[root@yangjianboinbeijingday2]#exprlength"zhongguoren"11

[root@yangjianboinbeijingday2]#exprsubstr"yangjianbo"22an

注意:它的截取子串,开始位置为1,而不是变量子串的从0开始。

4.bc命令的用法

bc是unix/linux下的计算器,可以处理小数。

[root@yangjianboinbeijing~]#seq-s"+"1001+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100[root@yangjianboinbeijing~]#seq-s"+"100|bc50505.awk命令的用法

适合计算整数和小数。

[sysadmin@192~]$echo"73"|awk'{print($1-$2)}'4[sysadmin@192~]$echo"7.83.6"|awk'{print($1-$2)}'4.26.使用$[]做计算

7.计算变量值的长度的方法比较

1.echo${#变量名}

2.echo$(exprlength变量名)

3.echo${变量名}|wc-m

结论:使用内部函数耗时小,建议使用第一种方式。

8.read用法

-p:提示符

-t:超时

[root@yangjianboinbeijingday3]#catread.sh#!/bin/bashread-t5-p"inputyournumber":var1输入一个值,给变量var1,注意var1前面有空格echo$var1read-p的功能可以用echo-n替换。

1.条件测试语法

1.test<测试表达式>

[root@yangjianboinbeijingday3]#test-ffile&&echotrue||echofalsefalse[root@yangjianboinbeijingday3]#touchfile[root@yangjianboinbeijingday3]#test-ffile&&echotrue||echofalsetruetest!非的用法

[root@yangjianboinbeijingday3]#test!-ffile&&catfilecat:file:没有那个文件或目录[root@yangjianboinbeijingday3]#touchfile[root@yangjianboinbeijingday3]#test!-ffile&&catfile2.[<测试表达式>]

[root@yangjianboinbeijingday3]#[-ffile]&&echo1||echo00[root@yangjianboinbeijingday3]#ll总用量4-rw-r--r--1rootroot634月320:50read.sh[root@yangjianboinbeijingday3]#touchfile[root@yangjianboinbeijingday3]#[-ffile]&&echo1||echo01[root@yangjianboinbeijingday3]#[!-ffile]&&echo1||echo00[root@yangjianboinbeijingday3]#ll总用量4-rw-r--r--1rootroot04月321:07file-rw-r--r--1rootroot634月320:50read.sh[root@yangjianboinbeijingday3]#rm-rfilerm:是否删除普通空文件"file"?y[root@yangjianboinbeijingday3]#[!-ffile]&&echo1||echo01

3.[[<测试表达式>]]

说明:1和2是等价的,3为扩展的test命令。

在3中可以使用通配符进行模式匹配。

&&||><操作可以应用于[[]]中,但不能应用于[]中。

对整数进行关系运算,也可以使用shell的算术运算符。

2.文件测试表达式

1.关于某个文件名的文件类型判断。

-f该文件名是否存在且为文件

-d该文件名是否存在且为目录

-e该文件名是否存在

-s该文件名是否存在且为“非空”文件

2.关于某个文件名的权限检测。

-r该文件名是否存在且有可读的权限

-w该文件名是否存在且有可写的权限

-x该文件名是否存在且有可执行的权限

3.关于两个文件的之间的比较

-ntnewerthan判断file1是否比file2新

-otolderthan判断file1是否比file2旧

-ef判断两个文件是不是指向同一个inode

4.例子

1.如果测试的是变量,那么变量需要添加引号,否则会有误判。

[root@192~]#echo$oldboy[root@192~]#[-f$oldboy]&&echo1||echo01[root@192~]#[-f"$oldboy"]&&echo1||echo002.如果测试的是实体路径,那么有没有双引号,结果都是一样的。

[root@192~]#[-f/root/vhost.sh]&&echo1||echo01[root@192~]#[-f"/root/vhost.sh"]&&echo1||echo013.字符串测试表达式

注意:字符串测试一定要加双引号,如果不加,会带来逻辑错误。

=和!=两边一定要有空格,如果没有空格,会带来逻辑错误

=和!=可以判断两个字符串是否相同

4.整数二元比较

1.建议最好都是用-eq,-ne这些比较符号,因为<>在[]中会出现逻辑错误,如下面的例子

[root@yangjianboinbeijingday2]#[2>1]&&echo1||echo01[root@yangjianboinbeijingday2]#[2<1]&&echo1||echo01[root@yangjianboinbeijingday2]#[[2<1]]&&echo1||echo00如果是单中括号,不要使用符号,使用-eq,-ne,-gt,-lt等;或者使用双中括号。双中括号也可以使用-eq-ne-gt2.整数变量的比较

[root@192~]#a=55[root@192~]#b=66[root@192~]#[$a-gt$b]&&echo1||echo00[root@192~]#[$a-lt$b]&&echo1||echo015.逻辑操作符

1.例子

[root@192~]#[-f/etc/hosts-a-f/etc/resolv.conf]&&echo1||echo01如果在[]中使用&&||会有报错。-bash:[:missing`]'-bash:-f:commandnotfound[root@192~]#[[-f/etc/hosts&&-f/etc/resolv.conf]]&&echo1||echo01如果在[[]]中使用-a-o也会有报错-bash:syntaxerrorinconditionalexpression-bash:syntaxerrornear`-a'6.测试表达式的区别

1.单分支结构

1.语法:

if[条件]

then

指令

fi

或者

if[条件];then

2.单分支结构举例

1.比较两个数字的大小

[root@yangjianboinbeijingday4]#viif1.sh#!/bin/bashif[3-gt2];thenecho1firead读入参数[root@yangjianboinbeijingday4]#catif2.sh#!/bin/bashread-p"inputnum1":num1read-p"inputnum2":num2if[$num1-gt$num2];thenecho1fi以位置参数的形式输入值。[root@yangjianboinbeijingday4]#catif3.sh#!/bin/bashif[$1-gt$2];thenecho1fi/bin/bashif3.sh312.开发脚本实现如果/server/scripts/下面存在if4.sh就输出到屏幕。

注意:如果执行脚本后发现该if4.sh不存在,就自动创建这个if4.sh脚本。

#!/bin/bashscriptname=/server/scripts/day4/if4.shif[-e$scriptname];thenecho"existif4.sh"else`touch$scriptname`fi变量名称最好用大写,当然小写也没有问题。3.判断系统内存大小,小于100M,就邮件报警。

[root@yangjianboinbeijingday4]#catif-free.sh#!/bin/bashMEMORY=`free-m|awk'NR==3{print$4}'`if[$MEMORY-lt2000];thenecho"memoryis$MEMORY"|mail-s"memory"329624434@qq.comfi4.判断系统的根目录剩余空间大小,小于50G,就邮件报警

#!/bin/bashFREE_DISK=`df-h|awk'NR==2{print$4}'`JIELUN=`echo"${FREE_DISK//G/}<50"|bc`if[${JIELUN}-eq1];thenecho"free_diskis${FREE_DISK}"|mail-s"free_disk"329624434@qq.comfi3.if双分支结构讲解和实例

1.双分支结构

if[条件一];then

执行语句

else

2.实例

1.比较两个整数的大小。

[root@yangjianboinbeijingday4]#catif-double.sh#!/bin/basha=10b=11if[$a-gt$b];thenecho$aelseecho$bfi2.使用传参的方式。

[root@yangjianboinbeijingday4]#catif-double2.sh#!/bin/bashif[$1-gt$2];thenecho$1elseecho$2fi3.脚本判断需要添加几个参数,如果参数不正确就退出,并报错

[root@yangjianboinbeijingday4]#catif-double3.sh#!/bin/bashif[$#-ne2];thenecho"ERROR:$0num1num2"exit1fiif[$1-gt$2];thenecho$1elseecho$2fi4.判断输入的参数是不是数字,使用sed命令。

[root@yangjianboinbeijingday4]#catif-double5.sh#!/bin/bashif[$#-ne2];thenecho"ERROR:$0num1num2"exit1fi[-z"`echo$1|sed's/[a-z]//g'`"]&&{echo"num1mustbeint."exit1}[-z"`echo$2|sed's/[a-z]//g'`"]&&{echo"num2mustbeint."exit1}if[$1-gt$2];thenecho$1elseecho$2fi5.使用read读入变量参数,判断为数字,不能为字符串,比较两个数字的大小。

#!/bin/bashread-p"pleaseinputyournumber:"num1num2if[-z$num1];thenecho"$0needtwoargs!"exit1elif[-z$num2];thenecho"$0needtwoargs!"exit1else[-z`echo$num1|sed's/[a-z]//g'`]&&{echo"num1mustbeint"exit1}[-z`echo$num2|sed's/[a-z]//g'`]&&{echo"num2mustbeint"exit1}if[$num1-gt$num2];thenecho"$num1>$num2"elif[$num1-lt$num2];thenecho"$num1<$num2"elseecho"$num1=$num2"fifi4.if条件语句企业实例

1.生产监控mysql服务

1.监控mysql服务是否正常启动,如果未正常启动,就启动mysql服务。

通过端口来判断,mysql服务是不是在运行中。[root@yangjianboinbeijingday4]#catmonitor_mysql.sh#!/bin/bash#monitormysqlserverlsof-i:3306>/dev/null&&echo$>/dev/nullif[$-eq0];thenecho"mysqlserverisstarting!"elseecho`systemctlstartmysqld.service`>/dev/nullecho"mysqld.servicestartsuccessful!"fi或者使用netstat-lnt|grep3306|wc-lps-ef|grepmysqld注意:如果过滤进程数,不要让脚本带有mysql字样。涉及到数据库,脚本使用db字样。

如果没有启动,就启动,再对启动的结果进行判断,如果发现没有成功,就彻底杀死,再启动mysql。

2.监控mysql服务,通过连接mysql监控。

[root@yangjianboinbeijingday4]#catmonitor_mysql_pid_port.sh#!/bin/bash#monitormysqlservermysql-uroot-p123456-e"selectversion();">/dev/null&&echo$>/dev/nullif[$-eq0];thenecho"mysqlserverisstarting!"elseecho`systemctlstartmysqld.service`>/dev/nullecho"mysqld.servicestartsuccessful!"fi3.监控mysql服务,通过PHP/JAVA程序监控mysql。

2.监控apache和nginx服务

1.通过本地端口或进程监控。

#!/bin/bashNGX_NUM=`netstat-lntp|grepnginx|wc-l`if[$NGX_NUM-gt0];thenecho"nginxisstarting"else/etc/init.d/nginxstartecho"nginxisstartsucessful"fi2.通过远程URL监控。wget或者curl。

1.使用传参的方式(要判断传入的参数的个数和传入的是否是整数)

#!/bin/basha=$1b=$2if[$#-ne2];thenecho"USAGE:$0numberistwo"exit200fiexpr$a+1>/dev/nullRET_a=$expr$b+1>/dev/nullRET_b=$if[$RET_a-ne0-o$RET_b-ne0];thenecho"thenumbermustbeint"exit100fiif[$a-gt$b];thenecho"$a>$b"elif[$a-lt$b];thenecho"$a<$b"elseecho"$a=$b"fi2.使用read读取的方式

#!/bin/bashread-p"inserttotwonumber:"abexpr$a+0>/dev/nullRET_a=$expr$b+0>/dev/nullRET_b=$if[-z"$a"]||[-z"$b"];thenecho"thenumberistwo"exit200fiif[$RET_a-ne0-o$RET_b-ne0];thenecho"thenumbermustbeint"exit100fiif[$a-gt$b];thenecho"$a>$b"elif[$a-lt$b];thenecho"$a<$b"elseecho"$a=$b"fi20.shell函数1.函数的定义

function函数名(){指令returnn}2.函数的调用

1.不带参数

函数名

2.带参数

函数名参数1参数2

3.函数的使用说明

1.执行函数时,不需要function和函数后的小括号

2.函数的定义必须在执行的程序前面定义或加载

3.shell执行系统中各种程序的执行顺序为:系统别名-函数-系统命令-可执行文件

4.函数执行时,会调用环境变量,还有自己定义的局部变量以及特殊位置参数

5.在shell函数,return的功能与exit类似,return的作用是退出函数,而exit是退出脚本文件

6.如果函数在一个单独的文件中,被脚本加载时,需要使用source或者.来加载(一个点)

4.范例

1.基本

[root@mysql-37scripts]#cathanshu.sh#!/bin/basholdboyoldboy(){echo"Iamyangjianbo!"}functionoldgirl(){echo"Iamqiwei!"}oldboyoldgirl2.分离函数体和执行函数

1.函数体

[root@mysql-37scripts]#cathanshu_fenli.sh#!/bin/bash#createdbyyangjianboat2019-09-17functionyangjianbo(){echo"Iamliudehua!"}只是定义了函数,但是没有执行函数

2.执行函数的脚本

[root@mysql-37scripts]#cathanshu_diaoyong.sh#!/bin/bash[-f/server/scripts/hanshu_fenli.sh]&&source/server/scripts/hanshu_fenli.sh||exit1yangjianbo注意函数体的脚本,要使用source或者.执行,否则提示找不到函数yangjianbo.

3.带参数[root@mysql-37scripts]#cathanshu_fenli.sh

#!/bin/bash#createdbyyangjianboat2019-09-17functionyangjianbo(){echo"Iamliudehua!$1"}[root@mysql-37scripts]#cathanshu_diaoyong.sh#!/bin/bash[-f/server/scripts/hanshu_fenli.sh]&&source/server/scripts/hanshu_fenli.sh||exit23yangjianbo$14.检查网站url

采用传入参数的方式

#!/bin/bash./etc/init.d/functionsfunctionusage(){echo"USAGE$0:onlyone"exit1}functioncheck_url(){wget--spider-q-o/dev/null--tries=1-T5$1if[$-eq0];thenaction"thewebserverisOK"/bin/trueelseaction"thewebserverisnotOK"/bin/falsefi}functionmain(){if[$#-ne1];thenusageficheck_url$1}main$*执行脚本:/bin/bashtest.shwww.baidu.com5.简单例子:

[root@yangjianboinbeijingday5]#catscript1.sh#!/bin/bash#Soursefunctionlibrary../etc/init.d/functionsif["$1"=="start"]thenaction"nginxstarting."/bin/trueelif["$1"=="stop"]thenaction"nginxisstopped."/bin/trueelseaction"nginxisstart"/bin/falsefi[root@yangjianboinbeijingday5]#shscript1.shnginxisstart[失败][root@yangjianboinbeijingday5]#shscript1.shstartnginxstarting.[确定][root@yangjianboinbeijingday5]#shscript1.shstopnginxisstopped.[确定]6.利用shell函数开发一键优化系统脚本

1.针对centos6的一键优化

1.服务启动脚本

#!/bin/bashif[$#-ne1];thenecho$"usage:$0{start|stop|restart}"exit1fiif["$1"=="start"];thenrsync--daemonsleep2if[`netstat-lntp|greprsync|wc-l`-ge1];thenecho"rsyncdisstarted."exit0fielif["$1"=="stop"];thenkillallrsync&>/dev/nullsleep2if[`netstat-lntp|greprsync|wc-l`-eq0];thenecho"rsyncdisstopped."exit0fielif["$1"=="restart"];thenkillallrsyncsleep1killpro=`netstat-lntp|greprsync|wc-l`rsync--daemonsleep1startpro=`netstat-lntp|greprsync|wc-l`if[$killpro-eq0-a$startpro-ge1];thenecho"rsyncdisrestarted."exit0fielseecho$"usage:$0{start|stop|restart}"exit1fi2.改造为函数

#!/bin/bashfunctioncheck_canshu(){echo$"usage:$0{start|stop|restart}"exit1}functionstart(){rsync--daemonsleep2if[`netstat-lntp|greprsync|wc-l`-ge1];thenecho"rsyncdisstarted."exit0fi}functionstop(){killallrsync&>/dev/nullsleep2if[`netstat-lntp|greprsync|wc-l`-eq0];thenecho"rsyncdisstopped."exit0fi}functionrestart(){killallrsyncsleep1killpro=`netstat-lntp|greprsync|wc-l`rsync--daemonsleep1startpro=`netstat-lntp|greprsync|wc-l`if[$killpro-eq0-a$startpro-ge1];thenecho"rsyncdisrestarted."exit0fi}functionmain(){if[$#-ne1];thencheck_canshufiif["$1"=="start"];thenstartelif["$1"=="stop"];thenstopelif["$1"=="restart"];thenrestartelsecheck_canshufi}main21.case条件语句的应用实践1.语法

case"条件"in

值1)执行1

;;

值2)执行2

*)执行3

esac

1.根据用户的输入判断用户输入的是哪个数字

#!/bin/bashread-p"inputyournumber:"numbercase"$number"in1)echo"youinputthenumberis1";;2)echo"youinputthenumberis2";;[3-9])echo"youinputthenumberis$number";;*)echo$"usage:$0youinput1-9number"esac2.往某个文件添加用户

#!/bin/bash./etc/init.d/functionsFILE_PATH=/etc/openvpn_authfile.conf[!-f$FILE_PATH]&&touch$FILE_PATHusage(){cat</dev/null2>&1;thenaction$"vpnuser,$1isexist"/bin/falseexitelsechattr-i${FILE_PATH}/bin/cp${FILE_PATH}${FILE_PATH}.$(date+%F%T)echo"$1">>${FILE_PATH}[$-eq0]&&action$"Add$1"/bin/truechattr+i${FILE_PATH}fi;;-d|-del)shiftif[`grep"\b$1\b"${FILE_PATH}|wc-l`-lt1];thenaction$"vpnuser,$1isnotexist."/bin/falseexitelsechattr-i${FILE_PATH}/bin/cp${FILE_PATH}${FILE_PATH}.$(date+%F%T)sed-i"/^${1}$/d"${FILE_PATH}[$-eq0]&&action$"Del$1"/bin/truechattr+i${FILE_PATH}fi;;-s|-search)shiftif[`grep-w"$1"${FILE_PATH}|wc-l`-lt1];thenecho$"vpnuser,$1isnotexist.";exitelseecho$"vpnuser,$1isexist.";exitfi;;*)usageexitesac22.while循环和until循环的应用实践1.while循环的语法

while<条件表达式>do指令done2.while循环执行流程的逻辑图

3.until循环的语法

until<条件表达式>do指令done4.当型和直到型循环的基本范例

1.持续查看uptime

#!/bin/bashwhiletruedouptimesleep2done5.shell脚本后台运行

2.例子

开启两个脚本,都放到后台执行

/bin/bashwhile.sh&

/bin/bashwhile2.sh&

通过jobs命令,查看当前任务的编号

想把其中一个放到前台执行,fg1

如果想把1又放到后台执行,先ctrl+z暂停,然后执行bg1,就放到后台执行了。

想杀掉一个任务,kill%1

6.while和until的例子

1.打印出54321

#!/bin/bashi=5while[$i-gt0]doecho$i>>/tmp/1.txt((i--))done#!/bin/bashi=5until[$i-lt1]doecho$i>>/tmp/2.txt((i--))done2.计算从1加到100之和

#!/bin/bashi=1sum=0while[$i-le100]do((sum=$sum+$i))((i++))doneecho$sum7.企业实战

1.使用while守护进程的方式监控网站,每隔10秒确定一次网站是否正常

#!/bin/bashsum=0exec<$1whilereadlinedosize=`echo$line|awk'{print$10}'`expr$size+1&>/dev/nullif[$-ne0];thencontinuefi((sum=sum+$size))doneecho"$1:total:${sum}bytes=`echo$((${sum}/1024))`KB"其它方法

awk'{print$10}'/usr/local/nginx/logs/test.zhenpin.com.log|awk'{sum+=$1}END{printsum}'4.分析nginx的访问日志,每一个小时一次,并且把访问的web的ip的PV次数超过500的,通过iptables禁止掉。

#!/bin/bashfile=$1whiletruedoawk'{print$1}'access.log|sort|uniq-c>/tmp/ip.txtexec>/tmp/iptables_drop.txtfidonesleep3600done5.分析系统的网络连接数

#!/bin/bashwhiletruedonetstat-ntp|awk-F'[:]+''{print$(NF-4)}'|sort|uniq-c>/tmp/ip.txtwhilereadlinedoip=`echo$line|awk'{print$2}'`count=`echo$line|awk'{print$1}'`if[$count-gt500]&&[`iptables-L-n|grep"$ip"|wc-l`-lt1];theniptables-IINPUT-s$ip-jDROPecho"$lineisdropped">>/tmp/iptables_drop.txtfidonesleep3600done8.while循环按行读文件的方式

1.使用exec方式

exec

cata.txt|whilereadlinedocmddone3.结尾使用<输入重定向

whilereadlinedocmddone

1.语法:for变量in<变量取值列表>

do

循环体

done

第二种语法:

for((exp1;exp2;exp3))

例子:

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

echo$i

2.for循环执行过程

2.for循环语句的基础实践

1.取值列表为普通数字或字符串

#!/bin/bashforiin12345doecho$idone2.取值列表为{}大括号的数字序列

#!/bin/bashforiin{5..10}doecho$idone3.取值列表为某个命令的输出结果

#!/bin/bashforiin`seq10100`doecho$idone

#!/bin/bashforiin$(seq510)doecho$idone4.列出某个目录下的所有文件和目录

#!/bin/bashforiin`ls`doecho$idone5.批量修改文件名称

#!/bin/bashforfilein`find/data/vendor/653/-typef`donewfile=`echo$file|sed's/%//g'`mv$file$newfiledone

#!/bin/bashforiin`ls`dorename".txt"".gif"$idone6.九九乘法表

#!/bin/bashCOLOR='\E[47;30m'RES='\E[0m'fornum1in`seq9`dofornum2in`seq9`doif[$num1-ge$num2];thenif(((num1*num2)>9));thenecho-ne"${COLOR}$num1*$num2=$((num1*num2))$RES"后面跟了一个空格elseecho-ne"${COLOR}$num1*$num2=$((num1*num2))$RES"后面跟了两个空格fifidoneecho""使用echo是为了换行done7.计算从1加到100的和

#!/bin/bashfor((i=1;i<=100;i++))do((sum=sum+i))doneecho$sum8.每5秒访问一次百度

1.mysql分库备份脚本

#!/bin/bashUSER=rootPASSWD="123.com"BACK_PATH=/server/backupMYSQL_CMD="mysql-u$USER-p$PASSWD"MYSQL_DUMP="mysqldump-u$USER-p$PASSWD-B"[!-d$BACK_PATH]&&mkdir-p$BACK_PATHfordbnamein`$MYSQL_CMD-e"showdatabases"|grep-Ev"mysql|performance_schema|information_schema|password|Database|sys"`do`$MYSQL_DUMP${dbname}|gzip>$BACK_PATH/${dbname}_$(date+%F).sql.gz`done2.mysql分库分表备份脚本

4.批量创建10个账号,密码随机

#!/bin/bash#createdbyyangjianborm-rf/tmp/password.logfornumin`seq-w10`douseraddoldboy_user${num}password=`echo$RANDOM|md5sum|cut-c1-8`echo${password}|passwd--stdinoldboy_user${num}echo-e"username:oldboy_user${num}\tpassword:${password}">>/tmp/password.logdone4.linux系统产生随机数的6种方法

1.通过系统环境变量($RANDOM)

RANDOM的随机数范围为0~32767,加密性不是很好,可以使用md5sum并截取结果的后n位

[root@192scripts]#echo$RANDOM|md5sum|cut-c1-8af861e2e

2.通过openssl产生随机数

[root@192scripts]#opensslrand-base6460|md5sum|cut-c2-972d02d47

3.通过date获得随机数

[root@192scripts]#date+%s$N1637826212

4.通过/dev/urandom配合chksum生成随机数

[root@192~]#head/dev/urandom|cksum

34835419542747

5.通过UUID生成随机数

[root@192~]#cat/proc/sys/kernel/random/uuidcfd1f306-4a1e-4770-9383-963e18851062

6.通过expect附带的mkpasswd生成随机数

yuminstallexpect-y

7.以上所有命令需要结合md5sum使用

5.select循环语句

1.语法

select变量名in[菜单取值列表]

2.案例

1.打印菜单

#!/bin/bashselectnameinyangjianboluoyinyichangkundoecho$namedone2.使用数组做变量列表

#!/bin/basharray=(liudehuazhangxueyoulimingguofucheng)selectnamein"${array[@]}"doecho$namedone3.调整select的默认提示符

#!/bin/basharray=(liudehuazhangxueyoulimingguofucheng)PS3="pleaseselectanumfrommenu:"selectnamein"${array[@]}"doecho$namedone24.循环控制及状态返回值的应用实践1.break,continue,exit,return的区别和对比

2.break,continue,exit功能执行流程图

1.break执行流程图

2.continue执行流程图

3.exit的执行流程图

3.break,continue,exit,return的基础案例

#!/bin/bashif[$#-ne1];thenecho"usage:break|continue|exit|return"fifunctiontest(){for((i=0;i<5;i++))doif[$i-eq3];then$*;fiecho$idoneecho"Iaminfunc"}test$*func_test=$if[`echo$*|grepreturn|wc-l`-eq1];thenecho"functionisexitstatus:$func_test"fiecho"ok"1.传入的参数为break,当for循环条件成立,那么直接跳出了for循环

[root@192scripts]#/bin/bashtest_break.shbreak012Iaminfuncok2.传入的参数为continue,当for循环成立,跳出了本次循环,进入了下一次循环

[root@192scripts]#/bin/bashtest_break.shcontinue0124Iaminfuncok3.传入的参数为exit,当for循环成立,直接退出了脚本,后面的代码就没有执行

[root@192scripts]#/bin/bashtest_break.shexit0124.传入的参数为return,当for循环成立,退出了函数,后面的代码仍然执行了。

[root@192scripts]#/bin/bashtest_break.shreturn012functionisexitstatus:0ok4.企业案例

1.服务器上添加或删除网卡的ip地址

2.把日志中每行的访问字节数所对应的字段数字相加,计算出总的访问量。

#!/bin/bashsum=0exec<$1whilereadlinedosize=`echo$line|awk'{print$10}'`expr$size+1&>/dev/nullif[$-ne0];thencontinuefi((sum=sum+$size))doneecho"$1:total:${sum}bytes=`echo$((${sum}/1024))`KB"3.提供了一个字符串(RANDOM随机数采用md5sum加密后取出连续10位的结果),请破解字符串对应的md5sum前的数字。

foriin{0..32767};doecho`echo$i|md5sum`,$i>>/tmp/1.txt;done#!/bin/bashmd5char="4fe8bf20ed"whilereadlinedoif[`echo$line|grep"$md5char"|wc-l`-eq1];thenecho$linebreakfidone

shell数组就是一个元素集合

2.数组的定义与增删改查

1.定义

语法:array=(value1value2value3...)

2.定义变量的方式

1.小括号直接赋值

[root@192scripts]#a=(123)[root@192scripts]#echo${a[*]}1232.小括号内采用键值对

[root@192scripts]#a=([15]=1[13]=2[14]=3)[root@192scripts]#echo${a[*]}2313.分别定义数组变量

[root@192scripts]#a[0]=yangjianbo;a[1]=luoying;a[2]=yichangkun[root@192scripts]#echo${a[*]}yangjianboluoyingyichangkun4.动态定义数组变量

[root@192scripts]#echo${a[*]}1.gif2.gif3.gifcase.shcheck_ip.shcheck_netstat.shcheck_url.shindex.htmlls_test.shmemeory_free.shopenvpn_user.shrsyndrsynd-funcationsolrslow.shtest_break.shtest_centos7.shtest_random.shtest_select.shtest.shtest_url.shuntil.shwhile2.shwhile.sh3.打印数组元素

echo${a[0]}默认下标从0开始的

echo${a[*]}打印出所有的元素

4.打印数组元素的个数

echo${#a[*]}

echo${#a[@]}

5.数组赋值

[root@192scripts]#a[0]=liudehua[root@192scripts]#echo${a[0]}liudehua6.数组删除

[root@192scripts]#unseta[0]删除某个元素[root@192scripts]#unseta删除整个变量7.数组内容的截取和替换

1.内容截取

[root@192~]#echo${a[*]}abcdefghijklmnopqrstuvwxyz[root@192~]#echo${a[*]:1:4}第一个冒号后面的数字表示从下标为1开始,第二个冒号后面的数字表示截取的长度bcde2.内容替换

[root@192~]#echo${a[*]/one/1}1twothreefourfivesixseveneightnineten3.shell数组开发实践

1.通过C语言型的for循环语句打印数组元素

#!/bin/basha=(onetwothreefourfive)for((i=0;i<${#a[*]};i++))doecho${a[i]}done使用普通的for循环

#!/bin/basha=(onetwothreefourfive)foriin${a[*]}doecho$idone2.通过while循环语句打印数组元素

#!/bin/basha=(onetwothreefourfive)i=0while((i<${#a[*]}));doecho${a[i]}((i++))done3.将命令结果作为数组元素定义并打印

#!/bin/basha=($(ls/root))foriin${a[*]};doecho$idone4.高级实战案例

1.利用bashfor循环打印下面这句话中字母数不大于6的单词

Iamoldboyteacherwelcometooldboytrainingclass

1.通过数组实现

#!/bin/basha=(Iamoldboyteacherwelcometooldboytrainingclass)for((i=0;i<${#a[*]};i++))doif[${#a[i]}-le6];thenecho${a[i]}fidone2.通过for循环实现

#!/bin/basha="Iamoldboyteacherwelcometooldboytrainingclass"foriin$a;doif[${#i}-le6];thenecho$ifidone3.通过awk实现

[root@192scripts]#a="Iamoldboyteacherwelcometooldboytrainingclass"[root@192scripts]#echo$a|awk'{for(i=1;i<=NF;i++)if(length($i)<=6)print$i}'2.批量检查多个网站地址是否正常

#!/bin/shUSER=rootPASSWORD=123456PORT=3307error=(11581159100810071062)MYSQLCMD="mysql-u$USER-p$PASSWORD-S/data/$PORT/mysql.sock"is_run(){[`lsof-i:$PORT|wc-l`-lt2]&&{echo"mysqlserverisstopped"exit1}}status_array(){status=($($MYSQLCMD-e"showslavestatus\G"|egrep"_Running|Last_Errno|Behind_Master"|awk'{print$NF}'))}status_error(){for((i=0;i<${#error[*]};i++))doif["$1"=="${error[$i]}"]then$MYSQLCMD-e"stopslave;setglobalsql_slave_skip_counter=1;startslave;"elseecho"MySQLslaveisfailed,errornois$1"fidone}judge_slave(){status_arrayif["${status[0]}"=="Yes"-a"${status[1]}"=="Yes"-a"${status[3]}"="0"]thenecho"MySQLslaveisok"elsestatus_error${status[2]}fi}main(){whiletruedois_runjudge_slavesleep60done}main26.shell脚本开发规范1.脚本基本规范

1.第一行指定脚本解释器。/bin/bash

2.从第二行开始添加日期,作者,功能介绍,版本号

3.脚本命名以sh结尾

4.成对出现的符号,一次性写完

5.流程控制语句一次性写完

6.代码缩进让代码易读

7.字符串赋值给变量要加双引号

2.shell变量命名及引用变量规范

1.全局变量

必须大写

2.局部变量

驼峰语法

首字母大写

3.变量的引用规范

使用大括号引用变量${变量名}

变量内容为字符串时,加双引号"${变量名}"

变量内容为整数时,直接使用$变量名来引用

3.shell函数的命名及函数定义规范

1.函数名首字母大写

4.shell脚本高级命名规范

1.常规shell使用.sh后缀

2.模块的启动或停止start_模块名.shstop_模块名.sh

3.监控脚本*_mon.sh

4.控制脚本*_ctl.sh

1.常见脚本错误范例

1.if条件语句缺少结尾关键字

2.循环语句缺少关键字

3.成对符号落了单

4.中括号两端没空格

2.shell脚本调试技巧

1.使用dos2unix命令处理在windows下开发的脚本

dos2unixwhile.sh

yuminstalldos2unix-y

2.使用echo命令调试

3.使用bash命令参数调试

-n不会执行脚本,只会检查语法

-v先将脚本的内容输出到屏幕上,然后执行脚本,如果有错误,也会给出错误提示

-x将执行的脚本内容及输出显示到屏幕上,常用的参数

1.配置文件.vimrc的重要参数

1.安装Expect软件

2.Expect程序自动交互的重要命令及实践

1.spawn命令

语法:spawn[选项][需要自动交互的命令或程序]

spawnsshroot@192.168.10.200uptime

2.expect命令

获取spawn命令执行后的信息,看是否匹配,匹配就执行expect后面的动作

语法:expect表达式[动作]

expect"*password"{send"123456\r"}

expecteof

或者expect与send放在不同行

expect"*password"

send"123456\r"

多次匹配不同的字符串

expect{

"yes/no"{exp_send"yes\r";exp_continue}

"*password"{exp_send"123456\r"}

}

3.send命令

\r表示回车

\n表示换行

\t表示制表符

4.exp_continue命令

表示继续匹配

5.常用命令总结

3.expect程序变量

1.普通变量

语法:set变量名变量值

setpassword"123456"

打印变量

puts$变量名

2.特殊参数变量

1.位置参数

语法:[lindex$argvn]

#!/usr/bin/expect#definevarsetfile[lindex$argv0]sethost[lindex$argv1]setdir[lindex$argv2]send_user"$file\t$host\t$dir\n"puts"$file\t$host\t$dir\n"结果:

[root@192scripts]#expectteshu.expyangjianbo.log192.168.1.130/tmpyangjianbo.log192.168.1.130/tmpyangjianbo.log192.168.1.130/tmp2.传参的个数和脚本名参数

#!/usr/bin/expect#definevarsetfile[lindex$argv0]sethost[lindex$argv1]setdir[lindex$argv2]send_user"$file\t$host\t$dir\n"puts"$file\t$host\t$dir\n"puts"$argc\n"传参个数$argcputs"$argv0\n"传参脚本名$argv0,没有空格的4.expect的if条件语句

if{条件表达式}{指令}if{条件表达式}{指令}else{#固定格式,不能修改指令}2.例子

1.判断传参个数

#!/usr/bin/expectif{$argc!=3}{send_user"usage:expect$argv0filehostdir\n"exit}#definevarsetfile[lindex$argv0]sethost[lindex$argv1]setdir[lindex$argv2]send_user"$file\t$host\t$dir\n"puts"$file\t$host\t$dir\n"puts"$argc\n"puts"$argv0\n"2.判断传参个数,不管是否符合都给予提示

#!/usr/bin/expectif{$argc!=3}{send_user"usage:expect$argv0filehostdir\n"exit}else{puts"good."}#definevarsetfile[lindex$argv0]sethost[lindex$argv1]setdir[lindex$argv2]send_user"$file\t$host\t$dir\n"puts"$file\t$host\t$dir\n"puts"$argc\n"puts"$argv0\n"5.expect中的关键字

1.eof

用于匹配结束符

2.timeout

6.生产场景下的实例

1.批量执行命令

#!/usr/bin/expectif{$argc!=2}{send_user"usage:expect$argv0ipcmd\n"exit}#definevarsetip[lindex$argv0]setcmd[lindex$argv1]setpassword"**********"spawnssh-p11984zhangshaohua1510@$ip$cmdexpect{"yes/no"{send"yes\r";exp_continue}"*password"{send"$password\r"}}expecteof再加一个shell脚本,for循环,用来遍历多个机器ip

#!/usr/bin/expectif{$argc!=3}{puts"usage:expect$argv0filehostdir"exit}#definevarsetfile[lindex$argv0]sethost[lindex$argv1]setdir[lindex$argv2]setpassword"***************"spawnscp-P11984-rp$filezhangshaohua1510@$host:$direxpect{"yes/no"{send"yes\r";exp_continue}"*password"{send"$password\r"}}expecteof再加一个脚本,执行for循环,遍历多台机器

#!/usr/bin/expectif{$argc!=2}{send_user"usage:expect$argv0filehost\n"exit}#definevarsetfile[lindex$argv0]sethost[lindex$argv1]setpassword"huazai007@zhenpin.com"spawnssh-copy-id-i$file"-p11984zhangshaohua1510@$host"expect{"yes/no"{send"yes\r";exp_continue}"*password"{send"$password\r"}}expecteof加一个for循环脚本,遍历多个机器

#!/bin/bashforiin191192193194doexpect/server/scripts/ssh-copy.exp~/.ssh/id_rsa.pub192.168.2.$idone

THE END
1.免费测发型app推荐扫一扫测发型的软件下载拍照测发所以,今天就给小伙伴们分享一些可以帮助大家免费测发型的app大全,里面包括了换发型测脸型app、发型屋app、试发型相机app等等,让你可以在手机app上随意挑选感兴趣的发型,结合一张自拍,AI系统就可以一键帮您生成对应发型的造型,专业的发型模拟,无需去找发型师,对此有兴趣的小伙伴可以来下载体验。https://www.ddooo.com/zt/fxsjrj.htm
2.扫一扫测脸型配发型app手机扫一扫测脸型软件下载百度明星脸app是很有趣的手机拍照软件,通过这个软件用户可以计算自己的脸型与哪位明星最相近,很有趣的哦,还可以将自己测得的结果分享出去,让大家都可以看到你的测试,有兴趣 脸型测试配发型软件 16.89M / 2017-12-21 / v1.2.0 安卓版 评分: 下载 http://www.downyi.com/key/sysclxrj/
3.百度扫一扫自己脸型配发型摘要 百度扫一扫自己脸型配发型步骤如下,1.点开百度2点右上角相机3选择人相4进行拍照识别5选择合适的发型 咨询记录 · 回答于2022-08-29 百度扫一扫自己脸型配发型 百度扫一扫自己脸型配发型步骤如下,1.点开百度2点右上角相机3选择人相4进行拍照识别5选择合适的发型 百度,全球最大的中文搜索引擎、致力于https://wen.baidu.com/question/505407653324027444.html
4.扫一扫,人工智能测脸型我们知道发型能影响一个人的气质,所以发型是改变我们气质很重要的方法之一,而要想知道自己适合什么样的发型,就一定得先了解自己的脸型。 最近在网上看到很多朋友对自己的脸型比较困惑,然后直接发几张平面照片,让大家帮忙看下是什么脸型,其实做法判断出来的结果是很容易产生偏差的。 其实最好的办法是通过目前人工智能https://zhuanlan.zhihu.com/p/434411559
5.百度在线扫一扫测脸型配发型扫一扫测脸型配发型相关方法现在人工智能发展很快了,扫一扫测脸型,就像扫描二维码一样简单!还能依据脸型匹配发型。 步骤: 1. 在安卓或苹果商店搜“发型酷酷”; 2. 直接进首页,仅点击相机图标,其他图标不要点; 3. *好正脸拍照,撩起刘海,光线不要太暗,【就当自己在拍证件照】; https://m.liqucn.com/article/41286.wml
6.百度人工智能测面相百度众测有没有app?总之,百度测发型入口是一款非常实用的在线发型测试工具,它可以帮助你找到适合自己的发型,让你在人群中脱颖而出。 结语 以上就是关于百度测发型入口的介绍,希望对你有所帮助。如果你还有什么问题或建议,可以在下方留言,我们会尽快为你解答。 七、百度测发型在哪 https://tool.a5.cn/article/show/79909.html
7.百度扫一扫自己脸型配发型(免费拍脸测脸型)百度扫一扫自己脸型配发型(免费拍脸测脸型) 首先打开原相机,隔一米左右拍下自己的正脸无刘海图。(露出耳朵即可)接下来,找到额头、颧骨和下颌最宽处,连线后分别记为A、B、C,脸长记为D。(再看自己是平下巴还是尖下巴)现在,我们 首先打开原相机,隔一米左右拍下自己的正脸无刘海图。(露出耳朵即可) https://www.tjjntw.org.cn/news/6930.html
8.龙哥风向标20230411~20230418GPT拆解百万免费无资源广告下载编程集成开发环境(IDE):用于本地测丨试和调试 打包工具:用于将应用打包成可安装文件 通讯工具:用于与客户沟通和提供售后服务 需要开发的软件: 定制化ChatGPT:可能需要开发定制化的ChatGPT模型,以满足特定应用的编写需求。 ChatGPT最强对手Claude开放申请 盈利点:利用Claude开放申请的商机,可以开发基于Claude的智能对话系丨https://blog.csdn.net/wizardforcel/article/details/135933078
9.明星脸相似度测试APP百度明星脸相似度测试手机版这是一款可以测试你与明星的有多少共同点的app,几秒后你就可以知道自己与哪位明星最像!百度明星脸相似度测试可以帮助你改变角度,发型,服饰的方式,与你的偶像更加的相像,想要在手机上玩变脸游戏的用户快来试试kkx分享的这款百度明星脸相似度测试APP吧! http://www.kkx.net/az/35434.html
10.哪些人不适合剪短发(百度扫一扫自己脸型配发型)爱问知识人用上述的基线测试,距离越大越不适合留短发。这种头型不建议留短发,因为短发发型蓬松圆润才好看,太平的https://iask.sina.com.cn/b/new2EuP6ceJU1D.html
11.www.scmc百度百度发型操逼大黄片 啊啊…嗯嗯…不要 暂停时间操美女网站无遮挡 大学生日批批一区二区三区 一级又黄又爽黄带 最爽舒服的A片免费看 18操逼学生妹内射 日本欧美高清 希岛爱理空调维修在线 黄视频网站免费大全 日韩主播直播在线观看 日本午夜两性网 韩国伦理片2023 JlZZJlZZ国产免费A麻豆 K频道视频http://www.scmc-xa.com/xxxr/886288.htm
12.百度ai人脸识别颜值,超准的颜值打分器怎么样?百度ai人脸识别测脸是百度ai官方推广的人脸识别测脸源码。 目前已经有两个用于人脸识别的接口, V2和 V3。 在使用这两个接口的时候,消费者在使用的时候需要做出选择。 百度AI人脸识别相对准确。 外观评分根据系统中的评分标准进行,智能比对不会出现错误。 但识别时的角度、光线等因素都会影响外观的得分,所以外观的评http://www.bjhwtx.com/h-nd-44650.html
13.过年倒计时,百度APP帮你准备明星同款发型,稳赢!极客公园当然,为了保证在春节大战中取得胜利,只换个发型可能还远远不够,百度APP还友情附赠了专为你的脸型设计的妆容,步骤同测试明星同款发型,打开百度APP,在人脸模式下拍照搜索,秒秒钟获得妆容推荐! 分不清自己是什么脸型的化妆小白的机会来了,百度APP帮你分析好你属于鹅蛋脸、菱形脸、方形脸还是心形脸,底妆、眼妆、眉毛、腮https://www.geekpark.net/news/254234
14.百度扫一扫自己脸型配发型(免费拍脸测脸型)百度扫一扫自己脸型配发型(免费拍脸测脸型) 首先打开原相机,隔一米左右拍下自己的正脸无刘海图。(露出耳朵即可) 接下来,找到额头、颧骨和下颌最宽处,连线后分别记为A、B、C,脸长记为D。(再看自己是平下巴还是尖下巴) 现在,我们来看看这四条线的比例,哪一项最符合你的情况,并根据提示跳转到对应序列。https://www.5iyuyan.com/65169.html
15.www.zoo百度百度发型操逼大黄片 05.68MB 15%好评2523人) 91大神一二三区 伊伊人成亚洲综合人网7777 大鸡巴搞逼视频 62.32MB 35%好评750人) 84福利社区精品视频 午夜在线草 沈阳熟女和黑鬼呻吟 59.86MB 63%好评2416人) 外国老妇Wβ 亚洲中文字幕无码 免费视频乱伦导航 83.08MB 23%好评59人) 亚洲http://www.zoo-ya.com/xxxr64758400.html
16.quinovare.com/xxxr20342513/20241119/51509517.html百度百度发型操逼大黄片 777.43MB 314好评 韩国产精品视频 日本爱爱视频 狂操臭逼 142.12MB 836好评 欧美一区,二区,三区,四区三级片 大明嫡长子最新章节 色眯眯亚洲网站入口 734.83MB 9406好评 大饥荒中的女人全文 超碰碰97 強姧伦久久久久久久l234裸交 70.22MB 64好评 18模1.1.3下载 http://quinovare.com/xxxr20342513/20241119/51509517.html
17.www.sdmzgz.cn/go27402312.shtml百度百度发型操逼大黄片 农村国产妇女精品一吃春药的效果 粗机巴大挺进潘金莲身体小说 24.80MB 53%好评1439人) 少儿不宜的女人图片 午夜综合激情网 东北骚妇 10.19MB 65%好评20人) 午夜天堂一区人妻 日韩乱伦网 四川妇搡BBBB搡BBBB 72.50MB 57%好评788人) 国模冰冰高清 一开始就在里面漫画http://www.sdmzgz.cn/go27402312.shtml