本文共 7388 字,大约阅读时间需要 24 分钟。
变量:命名的内存空间:不同类型数据存储空间不一样;
数据存储方式:字符:1 如:1 既是字符又是数值;110,24 这种编码字符集美国成为ASCII数值:1,110 --> 0-255 之类,将十进制转成二进制,八位就够了,就是一个字节;整型数值和浮点型数值;存储一个汉字需要许多的0 和1 来存入到计算机;计算机内存最小存储单位为字节 1字节=8位;统一标准:字符集 来对应中文汉字或者其他语言;如 gbk;gb18030;utf8;否则会乱码;英文是127个变换,一个字节足以;数值:110+12=122 ,11010=1100字符运算:110+12=11012,11010=110110110110110110**十次变量:变量类型作用:1、数据存储格式;2、参与的运算;3、表示的数据范围;类型:字符;数值(整型(int)和浮点型(float))编程程序语言:强类型弱类型:bash :把所有的要存储的数据通通充当字符进行;不支持浮点型;布尔型 逻辑运算:true,false 非 异或与 : 1&&1 =1 ;1&&0=0;0&&1=0; 0&&0=0或:1||1=1; 1||0=1; 0||1=1; 0||0=0非: !1=0; !0=1异或:两个同时为真为假,两个为假为真;短路运算:与:对于与运算,对于左侧是0,结果必定是0;第一个为1,第二个必须参与运算;或:第一个为1,结果必定为1;第一个为0,第二个必须要参与运算;比如: ls /var&&echo “hello” 如果第一个是成功的,第二个命令必须得运行;第一个运行失败了,第二个直接不运行了,短路运算;ls /var||echo “hello”第一个成功,第二个不需要执行;第一个失败,执行第二个;ls /var&&echo “success”||echo “failure”第一个成功,直接返回;第一个失败,就执行第二个。id root &> /dev/null &&echo “exits”||echo “no such user”小结:shell基础特性,grepShell: #!/bin/bash过程式:以命令为中心对象式:以数据为中心grep:j文本过滤器(支持正则)PATTERN(魔数)REGEXP(正则)BRE(基本正则),ERE(扩展正则)BRE:字符匹配:‘.’(任意单个字符); ‘[]’(范围内任意单个字符); ‘[^]’ (范围外任意单个字符);次数匹配:‘’,匹配前面的字符任意次;’(\是转义)\?’:匹配前面字符0或者1次,可有可无;+:匹配前面字符至少一次;{m}精确指定次数。位置锚定:^:行首指定 :指定模式的最左侧$:行尾指定:指定模式的最右侧^patterns:用于模式匹配整行;^$:空行;^[[:space:]]$: 空白行\< 或者 \b:词首锚定:用于单词模式的左侧;\> 或者 \b词尾锚定:用于单词模式的右侧;\<PATTERN\>:匹配整个单词;分组符号()(xy)grep ‘(xy)+’grep.txtgrep ‘xy+’grep.txt X后面至少跟一个yNOtice:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3.....\1:从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符;(ab+(xy));\1:ab+(xy)\2: xy后向引用:引用前面的分组括号中的模式所匹配字符,(而非模式本身)
grep '([[:alpha:]]{1,3}t\>).*\1' /etc/passwdVim,sed,awk,grep ,nginxbash 脚本编程:过程式编程语言:顺序执行选择执行循环执行选择执行:
if 判断条件;then (单分支if)条件为真的分支代码结束if 判断条件;then (双分支if)
条件为真的分支代码else 条件为假的分支代码fivi adduser.sh
#!/bin/bashif [ $# -lt 1 ];thenecho "at least one argument."if id $1 &> /dev/null;then
echo "$1 exists."elseuseradd $1[ $? -eq 0 ]&& echo "$1" |passwd --stdin $1 &> /dev/nullfi多分支:if condition;thenIf-trueElif condition;thenIf-trueElif condition;thenIf-true......Else All-falseFi逐条件进行判断:第一次遇到“真”条件时,执行其分支,而后结束;示例:用户键入文件路径,脚本来判断文件类型;#!/bin/bashread -p “Enter a file path: ”filenameifbash编程之for循环
for 变量名 in 列表; do(跟if 的then 相似,换行“;”可以省略)循环体done执行机制:依次将列表中的元素赋值给"变量名",每次赋值后即执行一次循环体;直到列表中的元素耗尽,循环结束;示例:添加10个用户,user1---user3,密码同用户名;#!/bin/bashif [ ! $UID -eq 0 ];then echo "only root."exit 1fifor username in user1 user2 user3;doif id $username &> /dev/null;thenecho "$username exists."elseuseradd -M $username if [ $? -eq o ];thenecho "$username"|passwd --stdin $username &> /dev/nullecho "Add $username finished."fifi#!/bin/bash
if [ ! $UID -eq 0 ];then echo "only root."exit 1fifor i in {1..10};doif id user$i &> /dev/null;thenecho "user$i exists."elseuseradd -M user$i if [ $? -eq o ];thenecho "user$i"|passwd --stdin user$i &> /dev/nullecho "Add user$i finished."fifi列表生成方式:
(1)直接输出列表;(2)整数列表;(a)in {首数..尾数}(in {1..10})(b)$(seq [start [step]] end)(3)返回列表的命令$(COMMAND) (4)glob(b)变量引用$@,$*示例:判断某路径下所有文件的类型;
#!/bin/bashfor file in $(ls /var);do (/var/*)if [ -f /var/$file ];thenecho "common file." elif [ -L /var/$file ];thenecho "Symbolic file."elif [ -d /var/$file ];thenecho "Directory." elseecho "Other type."fidone查看tcp状态脚本
netstat -tan |grep "^tcp>/"|awk "{print $NF}"#!/bin/bash
estab=0listen=0other=0for status in $(netstat -tan |grep "^tcp>/"|awk "{print $NF}");do
if [ "$status" == "ESTABLISHED" ];thenlet estab++elif [ "$status" == "LISTEN" ];thenlet listen++else let other++fidoneecho "ESTABLISHED: $estab"echo "LISTEN: $listen"echo "Unkown: $other"练习1:/etc/rc.d/rc.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的文件输出为文件名加stop,以S开头的文件输出为文件名加start;
#!/bin/bashfor file in /etc/rc.d/rc.d/*;dobash编程之while循环
顺序执行选择执行条件测试运行命令或[[ expression ]]执行状态返回值:If Case循环执行将某代码段重复运行多次;重复运行多少次?循环次数事先已知:循环次数事先未知:必须有进入和退出条件:For, while,until函数:结构化编程及代码重用; functionFor 循环语法:For NAME in list; do循环体Done列表生成方式:(1)整数列表{start..end}$(seq start [[step]end])(2) glob/etc/rc.d/rc3.d/K*(3)命令Bash -n 判断脚本正确性;bash -x 查看脚本执行流程;示例: 监测10.0.27.1-20的网络状态#!/bin/bash #net="10.0.27"uphosts=0douwnhosts=0for i in {1..21};doping -c 1 -t 1 ${net}.${i} &> /dev/nullif [ $? -eq 0 ];thenecho "${net}.${i} is up"let uphosts++elseecho "${net}.${i} is down"let downhosts++fidoneecho "UP hosts: $uphosts"echo "Down hosts: $downhosts"While 循环:
While CONDITION;do循环体DoneCONDITION:循环控制条件CONDITION::循环控制条件:进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为false中止循环;因此CONDITION一般应该有循环控制变量;而此变量的值会在循环体不断被修正;示例:求100以内所有正整数之和;#!/bin/bashsum=0i=1while [ $i -le 100 ];dolet sum+=$ilet i++doneecho “$i”echo “summary: $sum”练习:用while批量添加用户use1---user10;
For与while区别就是 while 要手动控制循环练习:打印九九乘法表:(分别使用for和while循环实现)bash脚本编程:
While CONDITION;do循环体Done进入条件:CONDITION为True退出条件:falseUntil CONDITION;do循环体Done进入条件:false退出条件:true示例:求100以内所有正整数之和;For:#!/bin/bashsum=0i=1for i in {1..100};dolet sum+=$idoneecho "$i"echo "$sum"While: #!/bin/bashsum=0i=1while [ $i -le 100 ];dolet sum+=$i
let i++doneecho "$i"echo "$sum"Until:
#!/bin/bashi=1sum=0until [ $i -gt 100 ];dolet sum+=$ilet i++doneecho "$i"echo "$sum"利用until打印九九乘法表
#!/bin/bashj=1i=1until [ $j -gt 9 ];dountil [ $i -gt $j ];doecho -n -e "${i}X${j}=$[$i*$j]\t"let i++doneecho let i=1let j++done循环控制语句(用于循环体中):
CountiueContinue [N] 提前结束第N层的本轮循环,并直接进入下一轮判断;While CONDITION1;doCMD1......If CONDITION2;thenContinueFiCMDn....doneBreakBreak [n] 提前结束循环 CMD1......If CONDITION2;thenBrrakFiCMDn....done示例:求100以内所有偶数之和:要求遍历100以内的所有正整数;#!/bin/bashi=0sum=0until [ $i -gt 100 ];dolet i++if [ $[$i%2] -eq 1 ];thencontinuefilet sum+=$iDone;While true;do循环体Done示例2:用户选择,并显示完成后不退出脚本,而是提示用户继续选择显示其他内容:直接使用quit退出;
#!/bin/bashcat <<EOFcpu)show cpu information;mem)show memory information;disk)show disk information;quit)quit#################################EOFif [ $UID -gt 0 ];thenecho "Command mast be root."&& exit 1firead -p "Enter a option: " option
while [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ];doread -p "Wrong option!! Enter again: " optiondoneif [ "$option" == "cpu" ];thenlscpuelif [ "$option" == "mem" ];thencat /proc/meminfoelif [ "$option" == "disk" ];thenfdisk -lelseecho "Quit"fi示例2:每隔三秒到系统上获取已登录的用户的信息:条件判断:case语句
Case 变量引用 inPAT1) 分支1;;PAT2)分支2;;....*)默认分支 ;;Esac#!/bin/bash
cat <<EOFcpu)show cpu information;mem)show memory information;disk)show disk information;quit)quit#################################EOFif [ $UID -gt 0 ];thenecho "Command mast be root."&& exit 1firead -p "Enter a option: " option
while [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ];doread -p "Wrong option!! Enter again: " optiondonecase "$option" incpu)lscpu;;mem)cat /proc/meminfo;;disk)fdisk -l;;*)echo "Quit...."exit 0esac练习:写一个脚本,完成 如下需求;
(1)脚本可接收参数:start,stop,restart,status;(2)如果参数非此四者之一,提示使用格式后报错推出;(3)如果是start:则创建/var/lock/subsys/SCRIPT_NAME,并显示“启动成功”(4)如果是stop:则删除/var/lock/subsys/SCRIPT_NAME,并显示“停止完成”;考虑:如果事先已然停止过了,该如何处理?(5)如果是restart ,则先stop,再start;考虑:如果本来没有start,如何处理;(6)如果是status,则如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAME is running...”;如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAME is stopped...”;其中:SCEIPT_NAME为当前脚本名;转载于:https://blog.51cto.com/11041408/2049326