admin管理员组文章数量:1794759
bilibili
第十一章 Shell编程
第一节 基础正则表达式
正则表达式与通配符
- 正则表达式用来在文件中匹配符合条件的 字符串,正则是包含匹配。grep、awk、 sed等命令可以支持正则表达式。
- 通配符用来匹配符合条件的文件名,通配符是完全匹配。ls、find、cp这些命令不支持正则表达式,所以只能使用shell自己的通配符来进行匹配了。
基础正则表达式
元字符 | 作用 |
---|---|
* | 前一个字符匹配0次或任意多次。 |
. | 匹配除了换行符外任意一个字符。 |
^ | 匹配行首。例如:^hello会匹配以hello开头的行。 |
$ | 匹配行尾。例如:hello&会匹配以hello结尾的行。 |
[] | 匹配中括号中指定的任意一个字符,只匹配一个字符。 例如:[aoeiu] 匹配任意一个元音字母,[0-9] 匹配任意一位 数字, [a-z][0-9]匹配小写字和一位数字构成的两位字符。 |
[^] | 匹配除中括号的字符以外的任意一个字符。例如:[^0-9] 匹配 任意一位非数字字符,[^a-z] 表示任意一位非小写字母。 |
\ | 转义符。用于取消讲特殊符号的含义取消。 |
{n} | 表示其前面的字符恰好出现n次。例如:[0-9]{4} 匹配4位数 字,[1][3-8][0-9]{9} 匹配手机号码。 |
{n,} | 表示其前面的字符出现不小于n次。例如: [0-9]{2,} 表示两 位及以上的数字。 |
{n,m} | 表示其前面的字符至少出现n次,最多出现m次。例如: [a- z]{6,8} 匹配6到8位的小写字母。 |
-
“*”前一个字符匹配0次,或任意多次
- grep “a*” test_rule.txt
匹配所有内容,包括空白行 - grep “aa*” test_rule.txt
匹配至少包含有一个a的行 - grep “aaa*” test_rule.txt
匹配最少包含两个连续a的字符串 - grep “aaaaa*” test_rule.txt
则会匹配最少包含四个个连续a的字符串
- grep “a*” test_rule.txt
-
“.” 匹配除了换行符外任意一个字符
- grep “s…d” test_rule.txt
“s…d”会匹配在s和d这两个字母之间一定有两个字符的单词 - grep “s.*d” test_rule.txt
匹配在s和d字母之间有任意字符 - grep “.*” test_rule.txt
匹配所有内容 - “^”匹配行首,“$”匹配行尾
- grep “^M” test_rule.txt
匹配以大写“M”开头的行 - grep “n$” test_rule.txt
匹配以小写“n”结尾的行 - grep -n “^$” test_rule.txt
会匹配空白行
- grep “^M” test_rule.txt
- grep “s…d” test_rule.txt
-
“[]” 匹配中括号中指定的任意一个 字符,只匹配一个字符
- grep “s[ao]id” test_rule.txt
匹配s和i字母中,要不是a、要不是o - grep “[0-9]” test_rule.txt
匹配任意一个数字 - grep “^[a-z]” test_rule.txt
匹配用小写字母开头的行 - “[^]” 匹配除中括号的字符以外的 任意一个字符
- grep “^[^a-z]” test_rule.txt
匹配不用小写字母开头的行 - grep “^[^a-z A-Z]” test_rule.txt
匹配不用字母开头的行
- grep “^[^a-z]” test_rule.txt
- grep “s[ao]id” test_rule.txt
-
“\” 转义符
- grep “\.$” test_rule.txt
匹配使用“.”结尾的行 - “\{n\}”表示其前面的字符恰好出现n次
- grep “a\{3\}” test_rule.txt
匹配a字母连续出现三次的字符串 - grep “[0-9]\{3\}” test_rule.txt
匹配包含连续的三个数字的字符串 - “\{n,\}”表示其前面的字符出现不小于n次
- grep “^\[0-9]\{3,\}[a-z]” test_rule.txt
匹配最少用连续三个数字开头的行 - “\{n,m\}”匹配其前面的字符至少出现n次, 最多出现m次
- grep “sa\{1,3\}i” test_rule.txt
匹配在字母s和字母i之间有最少一个a,最多三个a
- grep “\.$” test_rule.txt
第一节 字符截取命令
第一讲 cut字段提取命令
cut [选项] 文件名
- -f 列号: 提取第几列
- -d 分隔符: 按照指定分隔符分割列
grep为提取行,cut提取列,而且cut提取的表格中,只能用制表符隔开不能用空格比如:
ID | Name | gender | Mark |
---|---|---|---|
1 | Li | M | 86 |
2 | Shen | M | 90 |
3 | Gao | M | 83 |
他们之间所有的都是拿Tab键隔开的,不是空格
- 提取多列时,用“,”隔开就可以
cut -f 2 student.txt
cut -f 2,3 student.txt - 有具体分割符时,也可以没有Tab键
cut -d “:” -f 1,3 /etc/passwd 以:为分隔符取1,3列 - 一般在使用cut命令的时候和管道符“|”连着使用
第二讲 printf命令
printf ‘输出类型输出格式’ 输出内容
- 输出类型:
- %ns: 输出字符串。n是数字指代输出几个字符
- %ni: 输出整数。n是数字指代输出几个数字
- %m.nf: 输出浮点数。m和n是数字,指代输出的整数 位数和小数位数。如%8.2f代表共输出8位数, 其中2位是小数,6位是整数。
- 输出格式:
- \a: 输出警告声音
- \b: 输出退格键,也就是Backspace键
- \f: 清除屏幕
- \n: 换行
- \r: 回车,也就是Enter键
- \t: 水平输出退格键,也就是Tab键 \v: 垂直输出退格键,也就是Tab键
例子:
printf %s 1 2 3 4 5 6
printf %s %s %s 1 2 3 4 5 6
printf ‘%s %s %s’ 1 2 3 4 5 6
printf ‘%s %s %s\n’ 1 2 3 4 5 6
只有最后一个会输出:
1 2 3
4 5 6
因为每有一个%s代表每几个字符输出一次
%s %s %s\n 代表没三个字符输出一次并且换行
他在与cat命令结合使用的时候,需要用$()把cat命令扩起来,使用这种命令赋予变量的方式,才能正确输出文件内容,但是具体格式还得用%s\t 或者%s\n控制
- printf主要在awk命令编程中使用
例子:
vi student.txt
ID Name PHP Linux MySQL Average
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66 - printf ‘%s’ $(cat student.txt)
不调整输出格式 - printf ‘%s\t %s\t %s\t %s\t %s\t %s\t \n’ $(cat student.txt)
调整格式输出
在awk命令的输出中支持print和printf命令
- print:print会在每个输出之后自动加入一 个换行符(Linux默认没有print命令)
- printf:printf是标准格式输出命令,并不会自动加入换行符,如果需要换行,需要手工加入换行符
第三讲 awk命令
awk命令也叫awk编程,可以识别非制表符的空格,用来解决cut命令解决不了的提取列工作,他是把需要提取的原文件一行一行扫描,扫描每一行中所需要点列,然后把它记录下来,在全部扫描完之后全部打印出来。
- awk ‘条件1{动作1} 条件2{动作2}…’ 文件名
-
条件(Pattern):
一般使用关系表达式作为条件- x > 10 判断变量 x是否大于10
- x>=10 大于等于
- x<=10 小于等于
-
动作(Action):
-
格式化输出流程控制语句**
例子:
vi student.txt
ID Name PHP Linux MySQL Average
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66 -
awk ‘{printf $2 “\t” $6 “\n”}’ student.txt
其中$2代表第2列,$6代表第6列,他可以识别非制表符的空格,单引号里面直接大括号代表没有条件,只要是输入有内容全部符合
取第2列和第6列
df -h | awk '{print $1 “\t” $3}'
提取 df -h命令显示之后的内容中第一列和第三列
-
需要注意:
printf 不可以自动换行,print 可以在末尾自动换行,但是在Linux系统中没有print命令,只有printf命令,但是在wak命令中两个都有,使用print可以少一个换行符。
- BEGIN
BEGIN必须是大写,他是一个条件。
awk ‘BEGIN{printf “This is a transcript \n” } {printf $2 “\t” $6 “\n”}’ student.txt
他会在打印出2,6行之前先输出一句话This is a transcript
它的作用是强者命令第一个执行他后面的语句,也可以指定分割符 - FS内置变量
FS是用来指定分隔符的
FS=“:”就是指定:为分隔符
例子:
cat /etc/passwd | grep “/bin/bash” |
awk 'BEGIN {FS=":"} {printf $1 “\t” $3 “\n”}'
这是打印用户信息地一和第三列,为什么需要在{FS=":"} 前加BEGIN呢?
因为如果你不加BEGIN你会发现除了第一行,其他都已经按格式打印出来了,但是只有第一行会照原样输出,因为awk默认是空格为分隔符,他在执行这条命令的时候,第一行数据已经被扫描了,所以来不及修改格式,但是加了BEGIN,他会第一步强制先把默认分隔符修改了。
- 关系运算符
cat student.txt | grep -v Name | awk '$6 >= 87 {printf $2 “\n” }'
第四讲 sed命令
sed命令
sed 是一种几乎包括在所有 UNIX 平台(包括 Linux)的轻量级流编辑器。sed主要是用来将数据进行选取、替换、删除、新增的命令。
它不仅可以修改文件内容,还可以修改命令结果,支持管道符操作,这就是与vim最大的区别
sed [选项] ‘[动作]’ 文件名
选项:
- -n: 一般sed命令会把所有数据都输出到屏幕 , 如果加入此选择,则只会把经过sed命令处理的行输出到屏幕。
- -e: 允许对输入数据应用多条sed命令编辑
- -i: 用sed的修改结果直接修改读取数据的文件, 而不是由屏幕输出
动作:
- a : 追加,在当前行后添加一行或多行。添加多行时,除最后 一行外,每行末尾需要用“\”代表数据未完结。
- c : 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结。
- i : 插入,在当期行前插入一行或多行。插入多行时,除最后 一行外,每行末尾需要用“\”代表数据未完结。
- d: 删除,删除指定的行。
- p:打印,输出指定的行。
- s:字串替换,用一个字符串替换另外一个字符串。格式为“行范 围s/旧字串/新字串/g”(和vim中的替换格式类似)。
例子:
sed ‘2p’ student.txt
查看文件的第二行会显示:
ID | Name | PHP | Linux | MySQL | Average |
---|---|---|---|---|---|
1 | Liming | 82 | 95 | 86 | 87.66 |
1 | Liming | 82 | 95 | 86 | 87.66 |
2 | Sc | 74 | 96 | 87 | 85.66 |
3 | Gao | 99 | 83 | 93 | 91.66 |
会发现多了一行,因为一般sed命令会把所有数据都输出到屏幕 ,只不过会先输出你想要的,这时候就需要-n配合
- sed -n ‘2p’ student.txt
输入-n后就没有多余的了 - sed ‘2,4d’ student.txt
删除第二行到第四行的数据,但不修改文件本身 - sed ‘2a hello’ student.txt
在第二行后追加hello - sed ‘2i hello \ world’ student.txt
在第二行前插入两行数据 - sed '2c No such person‘ student.txt
数据替换
字符串替换
sed ‘s/旧字串/新字串/g’ 文件名
- sed ‘3s/74/99/g’ student.txt
在第三行中,把74换成99 - sed -i ‘3s/74/99/g’ student.txt
sed操作的数据直接写入文件 - sed -e ‘s/Liming//g ; s/Gao//g’ student.txt
同时把“Liming”和“Gao”替换为空
第三节 字符处理命令
排序命令sort
sort [选项] 文件名
- -f:忽略大小写
- -n:以数值型进行排序,默认使用字符串型排序
- -r:反向排序
- -t:指定分隔符,默认是分隔符是制表符
- -k n[,m]: 按照指定的字段范围排序。从第n字段开始, m字段结束(默认到行尾)
例子:
- sort /etc/passwd
排序用户信息文件 - sort -r /etc/passwd
反向排序 - sort -t “:” -k 3,3 /etc/passwd
指定分隔符是“:”,用第三字段开头,第三字段结尾排序,就是只用第三字段排序,但是他不认识数字,会把数字当成字符串,认为3比11大 ,所以我需要加-n,进行数值排序 - sort -n -t “:” -k 3,3 /etc/passwd
统计命令wc
wc [选项] 文件名
- -l: 只统计行数
- -w: 只统计单词数
- -m: 只统计字符数
第四节 条件判断
- 按照文件类型进行判断
测试选项 | 作用 |
---|---|
-b 文件 | 判断该文件是否存在,并且是否为 块设备文件(是块设备文件 为真) |
-c文件 | 判断该文件是否存在,并且是否为字符设备文件(是字符设备 文件为真) |
-d 文件 | 判断该文件是否存在,并且是否为目录文件(是目录为真) |
-e 文件 | 判断该文件是否存在(存在为真) |
-f 文件 | 判断该文件是否存在,并且是否为普通文件(是普通文件为真) |
-L 文件 | 判断该文件是否存在,并且是否为管道文件(是管道文件为真) |
-p 文件 | 判断该文件是否存在,并且是否为符号链接文件(是符号链接 文件为真) |
-s 文件 | 判断该文件是否存在,并且是否为非空(非空为真) |
-S 文件 | 判断该文件是否存在,并且是否为套接字文件(是套接字文件 为真) |
两种判断格式
上面的表结合一下命令来判断
- test -e /root/install.log
- [ -e /root/install.log ]
中括号两边必须有空格,只能为[ -e /root/install.log ] ,不能是[-e /root/install.log]
在判断之后,使用echo $?来观察输出语句是否为真
[ -d /root ] && echo “yes” || echo "no"
第一个判断命令如果正确执行,则打印“yes”,否则打印“no”
- 按照文件权限进行判断
测试选项 | 作用 |
---|---|
-r 文件 | 判断该文件是否存在,并且是否该文件拥有读权限(有读 权限为真) |
-w文件 | 判断该文件是否存在,并且是否该文件拥有写权限(有写 权限为真) |
-x 文件 | 判断该文件是否存在,并且是否该文件拥有执行权限(有 执行权限为真) |
-u 文件 | 判断该文件是否存在,并且是否该文件拥有SUID权限(有 SUID权限为真) |
-g 文件 | 判断该文件是否存在,并且是否该文件拥有SGID权限(有 SGID权限为真) |
-k 文件 | 判断该文件是否存在,并且是否该文件拥有SBit权限(有 SBit权限为真) |
例子:
[ -w student.txt ] && echo “yes” || echo "no"
判断文件是拥有写权限的
不过系统不会区分,比如-w,只要所有者,所属组,其他人其中有一个有写权限,他就会返回yes,所以这个时候就需要我们自己写脚本
- 两个文件之间进行比较
测试选项 | 作用 |
---|---|
文件1 -nt 文件2 | 判断文件1的修改时间是否比文件2的新(如果新则为真) |
文件1 -ot 文件2 | 判断文件1的修改时间是否比文件2的旧(如果旧则为真) |
文件1 -ef 文件2 | 判断文件1是否和文件2的Inode号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
例子:
ln /root/student.txt /tmp/stu.txt
创建一个硬链接
[ /root/student.txt -ef /tmp/stu.txt ] && echo “yes” || echo “no” yes
用test测试
- 两个整数之间比较
测试选项 | 作用 |
---|---|
整数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(小于等于为真) |
例子:
-
[ 23 -ge 22 ] && echo “yes” || echo “no” yes
判断23是否大于等于22 -
[ 23 -le 22 ] && echo “yes” || echo “no” no
判断23是否小于等于22 -
字符串的判断
测试选项 | 作用 |
---|---|
-z 字符串 | 判断字符串是否为空(为空返回真) |
-n 字符串 | 判断字符串是否为非空(非空返回真) |
字串1 ==字串2 | 判断字符串1是否和字符串2相等(相等返回真) |
字串1 != 字串2 | 判断字符串1是否和字符串2不相等(不相等返回真) |
例子:
name=sc
给name变量赋值
[ -z “$name” ] && echo “yes” || echo “no” no
判断name变量是否为空,因为不为空,所以返回no
aa=11
bb=22
给变量aa和变量bb赋值
[ “$aa” == “$bb" ] && echo “yes” || echo "no"
判断两个变量的值是否相等,明显不相等 ,所以返回no
- 多重条件判断
测试选项 | 作用 |
---|---|
判断1 -a 判断2 | 逻辑与,判断1和判断2都成立,最终的结果才为真 |
判断1 -o 判断2 | 逻辑或,判断1和判断2有一个成立,最终的结果就为 真 |
!判断 | 逻辑非,使原始的判断式取反 |
例子:
aa=11
[ -n “$aa” -a “$aa” -gt 23 ] && echo “yes” || echo "no"
判断变量aa是否有值,同时判断变量aa的是否大于23
因为变量aa的值不大于23,所以虽然第一个判断值为真, 返回的结果也是假
aa=24
[ -n “$aa” -a “$aa” -gt 23 ] && echo “yes” || echo “no” yes
第五节 流程控制
第一讲 if语句
- 单分支if条件语句
if [ 条件判断式 ];then程序
fi
- 1
- 2
- 3
或者
if [ 条件判断式 ]then 程序
fi
- 1
- 2
- 3
- 4
单分支条件语句需要注意几个点
- if语句使用fi结尾,和一般语言使用大括号结尾不同
- [ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格
- then后面跟符合条件之后执行的程序,可以放在[]之后,用“;”分割。也可以换行写入,就不需要“;”了
例子:判断分区使用率
#!/bin/bash #统计根分区使用率
#Author: yangyang (E-mail: 1771566679@qq)
rate=$(df -h | grep "/dev/sda3" | awk '{print $5}' | cut -d "%" - f1)
#把根分区使用率作为变量值赋予变量rate
if [ $rate -ge 80 ]thenecho "Warning! /dev/sda3 is full!!"
fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 双分支if条件语句
if [ 条件判断式] then 条件成立时,执行的程序 else 条件不成立时,执行的另一个程序
fi
- 1
- 2
- 3
- 4
- 5
- 6
例子1:备份mysql数据库
#!/bin/bash
#备份mysql数据库。
# Author:yangyang (E-mail: 1771566679@qq)
ntpdate asia.pool.ntp &>/dev/null #同步系统时间
date=$(date +%y%m%d) #把当前系统时间按照“年月日”格式赋予变量date
size=$(du -sh /var/lib/mysql) #统计mysql数据库的大小,并把大小赋予size变量
if [ -d /tmp/dbbak ]thenecho "Date : $date!" > /tmp/dbbak/dbinfo.txtecho "Data size : $size" >> /tmp/dbbak/dbinfo.txtcd /tmp/dbbak
tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null rm -rf /tmp/dbbak/dbinfo.txtelsemkdir /tmp/dbbakecho "Date : $date!" > /tmp/dbbak/dbinfo.txtecho "Data size : $size" >> /tmp/dbbak/dbinfo.txtcd /tmp/dbbak
tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null rm -rf /tmp/dbbak/dbinfo.txt
fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
例子2:判断apache是否启动
#!/bin/bash
#Author: yangyang (E-mail:1771566679@qq)
port=$(nmap -sT 47.95.5.171 | grep tcp | grep http | awk '{print $2}')
#使用nmap命令扫描服务器,并截取apache服务的状态,赋予变量port if [ "$port" == "open" ] thenecho “$(date) httpd is ok!” >> /tmp/autostart-acc.log else/etc/rc.d/init.d/httpd start &>/dev/nullecho "$(date) restart httpd !!" >> /tmp/autostart-err.log
fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
nmap 远程扫描,检查服务是否启动
nmap -sT 扫描指定服务器上开启的TCP端口
- 多分支if条件语句
if [ 条件判断式1 ] then 当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ] then当条件判断式2成立时,执行程序2
...省略更多条件...
else 当所有条件都不成立时,最后执行此程序fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
例子:
#!/bin/bash #判断用户输入的是什么文件
#Author: yangyang (E-mail:1771566679@qq)
read -p "Please input a filename: " file
#接收键盘的输入,并赋予变量file if [ -z "$file" ]
#判断file变量是否为空 then echo "Error,please input a filename" exit 1 #定义错误返回值1
elif [ ! -e "$file" ] #判断file的值是否存在 thenecho "Your input is not a file!" exit 2 #定义错误返回值2
elif [ -f "$file" ] #判断file的值是否为普通文件 thenecho "$file is a regulare file!"
elif [ -d "$file" ] #判断file的值是否为目录文件 thenecho "$file is a directory!"
elseecho "$file is an other file!"
fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
第二讲 case语句
多分支case条件语句
case语句和if…elif…else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系。
case $变量名 in "值1")如果变量的值等于值1,则执行程序1 ;; "值2") 如果变量的值等于值2,则执行程序2 ;;
...省略其他分支... *) 如果变量的值都不是以上的值,则执行此程序
;;
esac
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
用于选择列表,打印选择车票
例子:
#!/bin/bash #判断用户输入
#Author: yangyang (E-mail: 1771566679@qq)
read -p "Please choose yes/no: " -t 30 cho
case $cho in "yes")echo "Your choose is yes!";; "no") echo "Your choose is no!";; *) echo "Your choose is error!";;
esac
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
第三讲 for循环
- 语法一
for 变量 in 值1 值2 值3
do 程序
done
- 1
- 2
- 3
- 4
例子
#!/bin/bash#Author:yangyang (Email:1771566679@qq)
#打印时间for time in morning noon afternoon eveningdoecho “This time is $time!”done
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
这种方法看起来很笨,需要把循环次数写入for,但是在系统管理的时候,当我们不确定循环次数的时候,比如解压缩一个文件里所有的压缩包,他会自动加入新的压缩包,这个时候我就需要用这种笨办法,这种后面加次数的也有一个好处,就是循环变量只要是由空格,或者回车,或者tab键隔开的,都可以算在内,所以才能和cat,ls等命令结合使用,cat命令执行之后显示的结果就是由回车隔开的,都可以算成是循环变量。在加入或者减少压缩包的时候,不需要修改脚本。
例子1:批量解压缩
#!/bin/bash#Author:yangyang (Email:1771566679@qq)
#批量解压缩软件包cd /lamp
ls *.tar.gz > ls.log #ls *.tar.gz 输出结果覆盖到ls.log文件
for i in $(cat ls.log)dotar -zxf $i $>/dev/nulldone
rm -rf /lamp/ls.log
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
例子2:打印车票
#!/bin/bash#Author:yangyang (Email:1771566679@qq)
#计算文件个数,并打印到屏幕cd /root/sh
ls *.sh > ls.log
for i in $(cat ls.log)doecho $yy=$(($y+1))done
rm -rf ls.log
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 语法二
for ((初始值;循环控制调节;变量变化))do程序done
- 1
- 2
- 3
- 4
例子:计算1加到100
#!/bin/bash#Author:yangyang (Email:1771566679@qq)
#计算1加到100s=0
for ((i=1;i<=100;i++))dos=$(($s+$i))done
echo "The sum of 1+2+...+99+100 is $s!"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
这种情况适用于知道循环次数
例子:批量创建用户
#!/bin/bash#Author:yangyang (Email:1771566679@qq)
#批量添加新用户read -p "Please input user name: " -t 30 name #输入用户名,等待时间30s
read -p "Please input the number of users: " -t 30 num #输入创建用户个数,等待时间30s
read -p "Please input the password of users: " -t 30 pass #输入用户密码,等待时间30s
if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ] #判断输入信息是否为空 theny=$(echo $num | sed s/'^[0-9]*$'//g) #这里是判断输入的用户个数是否为数字,sed后也可以把^[0-9]*$换为's/[0-9]//g'if [ -z "$y" ] #如果上一条语句输出不为空,就是输入的用户个数为数字,继续执行thenfor ((i=1;i<=$num;i++)) #开始循环do/usr/sbin/useradd "$name$i" &>/dev/null #建立用户echo $pass | /usr/bin/passwd --stdin "$name$i" &>/dev/null #设置用户密码,与用户名相同doneecho "Build seccees!"fi
fi
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
如果输入的时候输错了需要按,ctrl+退格键
第四讲 while循环与until循环
while循环
while循环是不定循环,也称作条件循环 。只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。这就和for的固定循环不太一样了。
while [ 条件判断式 ] do 程序 done
- 1
- 2
- 3
- 4
例子:从1加到100
#!/bin/bash #Author: yangyang (E-mail: 1771566679@qq)
#从1加到100i=1
s=0
while [ $i -le 100 ] #如果变量i的值小于等于100,则执行循环 do s=$(( $s+$i ))i=$(( $i+1 )) done
echo "The sum is: $s"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
until循环
until循环,和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。
until [ 条件判断式 ] do 程序 done
- 1
- 2
- 3
- 4
例子:从1加到100
#!/bin/bash #Author: yangyang (E-mail: 1771566679@qq)
#从1加到100i=1
s=0
until [ $i -gt 100 ] #循环直到变量i的值大于100,就停止循环 do s=$(( $s+$i ))i=$(( $i+1 )) done
echo "The sum is: $s"
本文标签: bilibili
版权声明:本文标题:bilibili 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1693428889a262486.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论