# sed 是什么? # sed : 字符流编辑器 Stream Editor; sed 擅长 替换、取行等 # sed 的功能与版本: 处理纯文本文件、日志、配置文件等 增长、删除、修改、查询 sed --version # 查看 sed 版本 # sed 语法格式: sed [选项] [sed指令] [输入文件] sed -i.bak 's#oldboy#oldgirl#g' oldboy.txt # -i --- sed命令的参数 ;sed --- sed命令,一个指令 ;g --- 小尾巴, 修饰
模式空间: sed 从文件读取一行文件后存入的缓冲区 (这个缓冲区是在内存中的)html
1. 查询 2. 增长 3. 删除 4. 替换 5. 拓展
# 建立测试环境: cat>person.txt<<EOF 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO EOF # cat>...<<EOF...EOF 表示建立文件 ; cat>>...<<EOF...EOF 表示向文件中追加内容 [root@NEO oldboy]# cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# # 1.1 显示某一行 [root@NEO oldboy]# sed -n '3p' person.txt # -n 表示 取消默认输出; '3p' 表示显示第3行 103,Alex,COO # 1.2 显示连续多行文本 # 显示第2行到第4行的内容,包含第2行和第4行 [root@NEO oldboy]# sed -n '2,4p' person.txt # '2,4p' 表示显示从第2行到第4行 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO # 1.3 显示包含 oldboy 的行到 包含104的行 [root@NEO oldboy]# sed -n '/oldboy/p' person.txt # '/oldboy/p' ---> 表示 包含 oldboy 的行 ;此时 该行命令 至关于 grep 'oldboy',但 grep 不能过滤范围 101,oldboy,CEO [root@NEO oldboy]# sed -n '/oldboy/,/104/p' person.txt # '/oldboy/,/104/p' ---> 包含 oldboy 的行 到 包含 104 的行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO [root@NEO oldboy]# sed -n '/oldboy/,/^104/p' person.txt # '/oldboy/,/^104/p' ---> 表示从包含 oldboy 的行到 以104开头的行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO # 1.4 过滤多个字符串 # 默认状况下,sed只支持基本正则表达式;sed 的 -r 参数,能够支持 扩展正则表达式 (| 和 ()) # 显示包含 oldboy 的行 或者 yy 的行 [root@NEO oldboy]# egrep 'oldboy|yy' person.txt 101,oldboy,CEO 104,yy,CFO [root@NEO oldboy]# sed -rn '/oldboy|yy/p' person.txt # -r '/oldboy|yy/p' ---> 表示 包含 oldboy 或者 yy 的行 101,oldboy,CEO 104,yy,CFO # sed 命令经过正则表达式进行过滤时,至关于 egrep # 1.5 查询指定多行 [root@NEO oldboy]# sed -n '1p;3p' person.txt # '1p;3p' ---> 第1行 和 第3行; 多行之间用 逗号 分隔 101,oldboy,CEO 103,Alex,COO [root@NEO oldboy]# sed -n '1p;2,4p;5p' person.txt # , 和 ; 搭配使用 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed -n '/oldboy/p;3,5p' person.txt 101,oldboy,CEO 103,Alex,COO 104,yy,CFO 105,feixue,CIO
# 2.1 单行增长: # 在第3行后面增长一行内容 [root@NEO oldboy]# cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed '3a 103.5,Lee,UFO' person.txt # 3a 表示在第3行的后面增长一行内容,3a 后面的空格没有用,也能够不写 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 103.5,Lee,UFO 104,yy,CFO 105,feixue,CIO[root@NEO oldboy]# cat person.txt # sed '3a ' 命令并无真正修改文件内容,若是想要真正修改文件内容,能够用 sed 的 -i 参数 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed '3i 103.5,Lee,UFO' person.txt # 3i 表示在第3行的前面再增长一行内容;同理, 该命令也没有真正修改文件内容,想要真正修改文件内容也是加上 -i 参数 101,oldboy,CEO 102,zhangyao,CTO 103.5,Lee,UFO 103,Alex,COO 104,yy,CFO 105,feixue,CIO # 增长单选文本: a 参数 :追加 append,在指定行后添加一行或多行文本 i 参数 :插入 insert,在指定行前添加一行或多行文本 # 在最后一行插入: [root@NEO oldboy]# sed -n '$p' person.txt # 在 sed 命令中, $ 表示最后一行 105,feixue,CIO [root@NEO oldboy]# sed '$a 103.5,Lee,UFO' person.txt # 在最后一行插入一行内容 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO 103.5,Lee,UFO [root@NEO oldboy]# sed '$a new,new,new\nold,old,old' person.txt # 在最后一行增长多行内容,用 \n 分隔 (这种方法不经常使用;此命令已被 cat>>...<<EOF...EOF 替代,并且在最后一行的多行追加通常用 cat>> 方法) 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO new,new,new old,old,old
# 去除空行实战:删除最后一行 [root@NEO oldboy]# cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed '$d' person.txt # 删除最后一行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO [root@NEO oldboy]# sed '1,3d' person.txt # 删除第1行到第3行; d 表示 delete 104,yy,CFO 105,feixue,CIO # 企业案例:不显示文件中空行 [root@NEO oldboy]# vim person.txt [root@NEO oldboy]# cat -nA person.txt # cat 的 -n 参数表示显示 行号, -A 表示 显示结尾的 $ 1 101,oldboy,CEO$ 2 102,zhangyao,CTO$ 3 $ 4 103,Alex,COO$ 5 $ 6 104,yy,CFO$ 7 $ 8 105,feixue,CIO$ [root@NEO oldboy]# grep -v '^$' person.txt # grep -v 表示 排除 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed '/^$/d' person.txt # sed 的 /^$/ 表示空行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO # 另外一种方法: sed 的 ! 表示 取反; 在 p d 这些参数前面加 ! [root@NEO oldboy]# sed -n '/^$/p' person.txt # 显示空行 [root@NEO oldboy]# sed -n '/^$/!p' person.txt # 排除空行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# [root@NEO oldboy]# sed '$!d' person.txt # '$!d' : 不删除最后一行 105,feixue,CIO
# 文本替换: sed -i 's#neo#NEO#g' oldboy.log # s 单独使用 ---> 将每一行中 第一处匹配的字符串进行替换 # g (global:全局) ---> 每一行进行所有替换 --> sed 指令 s 的替换标志之一(全局替换) # sed 的 -i 参数 ---> 用于修改文件; -i.ori ---> 自动备份;先备份源文件,而后修改文件的内容 [root@NEO oldboy]# cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed 's#o#AAAA#' person.txt 101,AAAAldboy,CEO 102,zhangyaAAAA,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed 's#o#AAAA#g' person.txt 101,AAAAldbAAAAy,CEO 102,zhangyaAAAA,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO
[root@NEO oldboy]# x=oldboy # oldboy 赋值给 x [root@NEO oldboy]# y=oldgirl # oldgirl 赋值给 y (中间不要有空格) [root@NEO oldboy]# sed 's#$x#$y#g' person.txt # '' ---> 所见即所得,因此 '' 中的内容没有被解析 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed "s#$x#$y#g" person.txt # "" 中的特殊符号($ $() `` !)会被解析 ; $x 表示 x变量 101,oldgirl,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO # sed 的反向引用 :参考之前的
[root@NEO ~]# head -2 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin [root@NEO ~]# awk -F ":" 'NR==2{print $1,$2}' /etc/passwd bin x # awk 语法格式: # awk 参数 '模式{动做}' 文件 ---> awk 参数 '条件(找谁){干啥}' 文件
# 经过正则表达式做为模式 # awk 使用正则表达式做为模式 # 建立环境: mkdir -p /server/files/ cat >>/server/files/reg.txt<<EOF Zhang Dandan 41117397 :250:100:175 Zhang Xiaoyu 390320151 :155:90:201 Meng Feixue 80042789 :250:60:50 Wu Waiwai 70271111 :250:80:75 Liu Bingbing 41117483 :250:100:175 Wang Xiaoai 3515064655 :50:95:135 Zi Gege 1986787350 :250:168:200 Li Youjiu 918391635 :175:75:300 Lao Nanhai 918391635 :250:100:175 EOF # 第1表表示姓,第2列表示名字,第3列表示ID,第4列表示捐款金额 [root@NEO server]# cat /server/files/reg.txt Zhang Dandan 41117397 :250:100:175 Zhang Xiaoyu 390320151 :155:90:201 Meng Feixue 80042789 :250:60:50 Wu Waiwai 70271111 :250:80:75 Liu Bingbing 41117483 :250:100:175 Wang Xiaoai 3515064655 :50:95:135 Zi Gege 1986787350 :250:168:200 Li Youjiu 918391635 :175:75:300 Lao Nanhai 918391635 :250:100:175 [root@NEO server]# # 2.1 找出包含 111 的行: [root@NEO files]# pwd /server/files [root@NEO files]# awk '/111/' reg.txt Zhang Dandan 41117397 :250:100:175 Wu Waiwai 70271111 :250:80:75 Liu Bingbing 41117483 :250:100:175 # 其它的正则表达式的用法在 awk 没什么变化,但 ^ 和 $ 在 awk 中不太同样 ^ 表示 某一列中 以什么开头的字符串(以什么开头的列) : $3~/^oldboy/ 表示 第3列中 以 oldboy 开头的字符串, ~ 可理解成 包含 $ 表示 某一列中 以什么结尾的字符串(以什么结尾的列) : $3~/oldboy$/ 同理 # 2.2 显示Xiaoyu的姓名和ID号码 [root@NEO files]# awk '/Xiaoyu/' reg.txt # 只有模式(由于没有{});'/Xiaoyu/' 表示包含 Xiaoyu 的行,它至关于 '$0~/Xiaoyu/',即 把一整行看成一列, awk 的 $0 表示把一整行的内容放到了 $0 中(把一整行看成一列) Zhang Xiaoyu 390320151 :155:90:201 [root@NEO files]# awk '$0~/Xiaoyu/' reg.txt Zhang Xiaoyu 390320151 :155:90:201 [root@NEO files]# awk '/Xiaoyu/{print $1,$2,$3}' reg.txt # /Xiaoyu/ 表示包含 Xiaoyu 的行 Zhang Xiaoyu 390320151 [root@NEO files]# awk '$2~/Xiaoyu/{print $1,$2,$3}' reg.txt # $2~/Xiaoyu/ 表示 第2列(名字那一列)包含 Xiaoyu 的行 Zhang Xiaoyu 390320151 # 2.3 显示全部以41开头的ID号码的人的全名和ID号码 [root@NEO files]# awk '$3~/^41/{print $1,$2,$3}' reg.txt # $3~/^41/ ---> 第3列(ID那一列)以 41 开头 Zhang Dandan 41117397 Liu Bingbing 41117483 # 2.4 显示全部ID号码最后一位数字是1或5的人的全名 [root@NEO files]# awk '$3~/[15]$/{print $1,$2}' reg.txt # $3~/[15]$/ 表示模式( {}外面的就是模式 ), {print $1,$2} 表示动做 Zhang Xiaoyu Wu Waiwai Wang Xiaoai Li Youjiu Lao Nanhai # 2.5 显示Xiaoyu的捐款,每一个值都以 $ 开头,如 $520$200$135 # 4. awk 里面进行替换的方法 --- gsub 函数 : '{gsub(/要找的内容(支持正则)/,"替换成的内容",$列号)}' [root@NEO files]# awk '{gsub(/:/,"$",$4)}' reg.txt # 没有输出是由于 awk 没有默认输出 [root@NEO files]# awk '{gsub(/:/,"$",$4);print}' reg.txt # 再加上 ;print 就会有输出 Zhang Dandan 41117397 $250$100$175 Zhang Xiaoyu 390320151 $155$90$201 Meng Feixue 80042789 $250$60$50 Wu Waiwai 70271111 $250$80$75 Liu Bingbing 41117483 $250$100$175 Wang Xiaoai 3515064655 $50$95$135 Zi Gege 1986787350 $250$168$200 Li Youjiu 918391635 $175$75$300 Lao Nanhai 918391635 $250$100$175 # 第4列的 : 替换成了 $ # gsub(/目标/,"替换为何",第几列) # gsub(/目标/,"替换为何") === gsub(/目标/,"替换为何",$0) ---> 整行替换 [root@NEO files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$4);print}' reg.txt Zhang Xiaoyu 390320151 $155$90$201 [root@NEO files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$4);print $4}' reg.txt $155$90$201 [root@NEO files]# # gsub() 是awk 的一个函数
# 特殊模式: BEGIN 和 END BEGIN{} ---> BEGIN里面的内容,会在 awk 读取文件内容以前运行 # 通常用于测试、计算等 END{} ---> END里面的内容,会在 awk 读取文件的最后一行以后运行 (END很经常使用) # 用来显示最终结果(前面一直在计算,最后END显示结果) [root@NEO files]# awk 'BEGIN{print "this is beginning"}' # 只写了个BEGIN ,后面就不用接文件了 this is beginning [root@NEO files]# awk 'BEGIN{print "this is beginning"} {print NR,$0}' reg.txt # {print NR,$0} ---> NR 表示 行号 this is beginning # BEGIN的内容 1 Zhang Dandan 41117397 :250:100:175 2 Zhang Xiaoyu 390320151 :155:90:201 3 Meng Feixue 80042789 :250:60:50 4 Wu Waiwai 70271111 :250:80:75 5 Liu Bingbing 41117483 :250:100:175 6 Wang Xiaoai 3515064655 :50:95:135 7 Zi Gege 1986787350 :250:168:200 8 Li Youjiu 918391635 :175:75:300 9 Lao Nanhai 918391635 :250:100:175 # 统计 /etc/services 文件里面的空行数量 [root@NEO files]# awk '/^$/{print NR}' /etc/services # '/^$/{print NR}' 22 266 299 320 326 393 461 474 479 486 494 506 512 518 583 584 [root@NEO files]# awk '/^$/{i=i+1;print i}' /etc/services # i=i+1 表示 把 i+1 的结果赋值给 i ,每一个增长1,因此这个公式用来统计;i=i+1 也能够简写成 i++ ; i=i+1 和 print 之间用 ; 分隔 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@NEO files]# # i=i+1 === i++ ---> 用来统计 [root@NEO files]# awk '/^$/{i=i+1}END{print i}' /etc/services # {i=i+1}END{print i} ---> i=i+1 是先计算,END{print i} 表示 文件读取文件最后一行后 执行 {print i} 16 [root@NEO files]# awk '/^$/{i++}END{print i}' /etc/services # i++ 至关于 i=i+1 16
#awk数组-统计与计算 # awk 数组的组成: hotel[110]="张三" # hotel 表示 数组的名字(酒店名称), 110 表示数组的元素名称(房间号), 张三 表示 元素内容(房间内容) ; hotel[110] 组成了一个数组 [root@NEO files]# awk 'BEGIN{hotel[110]="NEO";hotel[114]="XO";print hotel[110],hotel[114]}' # 110]="NEO" ---> 建立数组;print hotel[110] ---> 把数组中的内容显示出来 NEO XO # 处理如下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题) http://www.etiantian.org/index.html http://www.etiantian.org/1.html http://post.etiantian.org/index.html http://mp3.etiantian.org/index.html http://www.etiantian.org/3.html http://post.etiantian.org/2.html [root@NEO files]# cat url.txt http://www.etiantian.org/index.html http://www.etiantian.org/1.html http://post.etiantian.org/index.html http://mp3.etiantian.org/index.html http://www.etiantian.org/3.html http://post.etiantian.org/2.html [root@NEO files]# awk -F "[/.]+" '{print $2}' url.txt # 让 $2 做为数组的元素 www www post mp3 www post # h[$2] 表示 把 第2列(www post mp3)做为元素名称组成一个数组;一共有 3个元素 # h[$2]++ 表示 每一个元素名称 遇到相同的元素名称时 加1,遇到不一样的元素名称时不作处理 # h["www"] 表示 www 这个元素名称中的 元素内容 [root@NEO files]# awk -F "[/.]+" '{h[$2]=h[$2]+1;print h["www"]}' url.txt 1 2 2 2 3 3 [root@NEO files]# # 显示全部元素的内容 [root@NEO files]# awk -F "[/.]+" '{h[$2]++}END{print h["www"],h["post"],h["mp3"]}' url.txt 3 2 1 # awk 本身提供的循环,可用于显示数组里面的内容: for(pol in h) ---> h是数组,pol 是h数组中的变量(数组的元素名称;遍历的也是数组的元素) [root@NEO files]# awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print pol}' url.txt www mp3 post # 遍历的是 数组的元素名称 [root@NEO files]# awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print h[pol]}' url.txt # 把 元素名称 放到 数组h中 3 1 2 [root@NEO files]# awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print pol,h[pol]}' url.txt www 3 mp3 1 post 2
熟练使用 vim 编辑器
熟练 SSH终端
熟练掌握 Linux经常使用命令
熟练掌握Linux正则表达式及三剑客命令(grep sed awk)
# 1. 什么是Shell ? # 命令解释器; 你输入的命令,谁来给你解释/运行 # CentOS默认的 Shell 是 bash : echo $SHELL /etc/passwd .sh 结尾的文件 file 命令也能够查看文件类型 [root@NEO ~]# echo $SHELL /bin/bash [root@NEO ~]# cat /etc/shells /bin/sh /bin/bash /sbin/nologin /bin/dash /bin/tcsh /bin/csh [root@NEO ~]# file /etc/init.d/iptables /etc/init.d/iptables: POSIX shell script text executable # shell script ---> shell脚本 # 2. 什么是Shell脚本? # 命令大礼包 --- 一个程序文件,包含若干行Linux命令语句 # 循环,条件语句 # 建立shell脚本: # 1. 统一脚本存放目录 # 如: /server/scripts/ # 2. 推荐使用 vim 编辑器编程脚本 # 由于 vim 自带颜色 # 3. 第一行指出由哪一个解释器来执行脚本中的内容: #!/bin/bash ---> #! 称为幻数,能被内核识别 ---> 必须写在第一行,若是不是第一行则为脚本注释行 ---> 双能够写为 #!/bin/sh # 4. 版权声明 # 5. 写一个简单脚本(切换目录显示文件属性)并运行 # 脚本目录示例: [root@NEO ~]# [root@NEO ~]# ls -l /server/scripts/ total 8 -rw-r--r-- 1 root root 66 Apr 7 23:22 ip.sh -rw-r--r-- 1 root root 9 Apr 7 14:30 show_date.sh # 脚本注释 & 版权声明: [root@NEO ~]# vim /server/scripts/ip.sh [root@NEO ~]# cat /server/scripts/ip.sh #!/bin/bash #!/bin/bash 表示 这个脚本是用 /bin/bash 运行解释的 # desc: show ip address # author: neo # time: 20190416 # version: v1.0 /sbin/ifconfig eth0 |awk -F "[ :]+" 'NR==2{print $4}' [root@NEO ~]# file /server/scripts/ip.sh /server/scripts/ip.sh: Bourne-Again shell script text executable [root@NEO ~]# /server/scripts/ip.sh # 正常运行脚本的方法:经过绝对路径 -bash: /server/scripts/ip.sh: Permission denied # 在linux 中建立的文件默认的权限是 644 [root@NEO ~]# sh /server/scripts/ip.sh # 之后在执行脚本的时候都是运行 sh 命令 10.0.0.200
# 3.1 什么是变量? # 用一个固定的字符串,替代更多更复杂的内容 # x=1 # devPath=/server/ # filelist=`ls` 或 $(ls) # 引用变量: $x 至关于 ${x} [root@NEO ~]# echo $PATH $LANG # 环境变量 /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin en_US.UTF-8 [root@NEO ~]# x=1 # 往变量中放值 ; x 是普通变量(局部变量) [root@NEO ~]# echo $x # 取出变量中的值 1 [root@NEO ~]# # 3.2 变量的分类: # 3.2.1 局部变量(普通变量): 只能在建立它们的Shell函数或Shell脚本中使用 定义变量: 变量名=value 变量名要求: 字母、数字、下划线组成,必须以字母或下划线开头 规范的变量名写法定义:见名知意 驼峰语法:首个单词字母小写,其他单词首字母大写 ---> oldAgeSex=1 把一个命令做为变量 普通字符串定义测试 [root@NEO ~]# week=10 [root@NEO ~]# echo $weekday # 此时系统认为 weekday 这个总体是个变量 [root@NEO ~]# echo ${week}day # $week 就至关于 ${week} 10day [root@NEO ~]# # 3.2.2 全局变量(环境变量): 大写,在Linux中绝大地方均可以用 在建立他们的Shell及其派生出来的子Shell中使用 分类: 查看全局变量: env ---> 只显示全局变量 bash内置的环境变量: Shell经过环境变量来肯定 登录用户名、命令路径、终端类型、登录日志等 LANG PAHT SEHLL UID 等 自定义环境变量: 建议全部环境变量名均为大写 必须用 export 命令定义 取消变量: unset 永久生效 [root@NEO ~]# echo $LANG $PATH $PS1 en_US.UTF-8 /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin [\u@\h \W]\$ [root@NEO ~]# # 全局变量 和 局部变量 [root@NEO ~]# vim /server/scripts/show_date.sh [root@NEO ~]# cat /server/scripts/show_date.sh #!/bin/hash # desc: # author: # time: # version: echo $OLDBOY [root@NEO ~]# OLDBOY=10 # 此时的 OLDBOY 是一个普通变量,在 /server/scripts/show_date.sh 这个脚本中没法使用 [root@NEO ~]# echo $OLDBOY 10 [root@NEO ~]# sh /server/scripts/show_date.sh # 输出为空,由于 OLDBOY 是个局部变量,在 这个脚本中没法使用 [root@NEO ~]# # 让普通变量变成全局问题的方法: export 命令; export 是临时生效;取消全局问题的方法 : unset 命令, unset 不但能取消全局变量,也能取消局部变量 [root@NEO ~]# export OLDBOY # 让 OLDBOY 这个普通变量 变成 全局变量 [root@NEO ~]# sh /server/scripts/show_date.sh 10 # 此时 OLDBOY 就能在 该脚本中使用了 [root@NEO ~]# [root@NEO ~]# env |grep OLDBOY OLDBOY=10 [root@NEO ~]# unset OLDBOY [root@NEO ~]# env |grep OLDBOY [root@NEO ~]# # 3.2.3 Shell 编程之环境变量相关的文件和目录: 全局环境变量配置文件: /etc/profile ---> 修改环境变量的文件 /etc/bashrc /etc/profile.d/ ---> 用户登录到系统 会运行这个目录下面的脚本 ;脚本要有执行权限 用户本身的环境变量配置文件: ~/.bash_profile ~/.bashrc # 修改 /etc/profile.d/ 下的文件 ---> 用户登录到系统会自动运行 [root@NEO ~]# ls /etc/profile.d/ colorls.csh cvs.csh glib2.csh lang.csh less.csh vim.csh which2.sh colorls.sh cvs.sh glib2.sh lang.sh less.sh vim.sh [root@NEO ~]# vim /etc/profile.d/show.sh [root@NEO ~]# cat /etc/profile.d/show.sh #!/bin/bash # desc: show ip address of eth0 # author: neo # time: 20190417 # version: v1.0 ip a s eth0 [root@NEO ~]# ll /etc/profile.d/show.sh -rw-r--r-- 1 root root 104 Apr 17 02:00 /etc/profile.d/show.sh [root@NEO ~]# chmod +x /etc/profile.d/show.sh [root@NEO ~]# ll /etc/profile.d/show.sh -rwxr-xr-x 1 root root 104 Apr 17 02:00 /etc/profile.d/show.sh WARNING! The remote SSH server rejected X11 forwarding request. Last login: Tue Apr 16 20:48:25 2019 from 10.0.0.1 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:26:b5:57 brd ff:ff:ff:ff:ff:ff inet 10.0.0.200/24 brd 10.0.0.255 scope global eth0 inet6 fe80::20c:29ff:fe26:b557/64 scope link valid_lft forever preferred_lft forever [root@NEO ~]# # 本身写的跳板机放到 /etc/profile.d/ 下面 # 特殊变量: # 位置变量: $0 (在脚本中) 获取当前执行的shell脚本的文件名 若是执行脚本带路径那么就包括脚本路径 模拟系统脚本使用 $0 $n n 表示数字;$n 表示 第n个参数 $# 表示参数的个数 # 进程状态变量 $? ---> 显示上一个命令的执行结果;命令执行正确 ---> 结果为0 , 命令执行错误 ---> 结果非0 ;软件安装后可用 $? 判断是否安装成功 # 位置变量: # 环境建立: [root@NEO scripts]# vim show_args.sh [root@NEO scripts]# cat show_args.sh #!/bin/bash # desc: # author: neo # time: # version: echo '$0:'$0 '$1:'$1 '$2:'$2 '$3:'$3 '$#:'$# # '$0:' 须要用单引号,双引号的话就被解析了 [root@NEO scripts]# sh show_args.sh $0:show_args.sh $1: $2: $3: $#:0 # $0 表示脚本的名字; $n 在脚本中表示第n个参数 [root@NEO scripts]# sh show_args.sh arg1 arg2 arg3 arg4 arg5 arg6 # 脚本后面能够跟参数 $0:show_args.sh $1:arg1 $2:arg2 $3:arg3 $#:6 # $# 表示参数的个数(脚本中一共有多少个参数) [root@NEO scripts]# ls /root/alex.oldboy.txt ls: cannot access /root/alex.oldboy.txt: No such file or directory [root@NEO scripts]# echo $? 2 # 执行错误 [root@NEO scripts]# ls /root/ alex.txt anaconda-ks.cfg data echotest.txt install.log.syslog oldboy-20171111.log [root@NEO scripts]# echo $? 0 # 执行正确 [root@NEO scripts]# # 变量赋值方法 --- read # 如何向变量中放内容? [root@NEO scripts]# vim show_args.sh [root@NEO scripts]# cat show_args.sh #!/bin/bash # desc: # author: neo # time: # version: x=1 y=2 echo $x $y [root@NEO scripts]# sh show_args.sh 1 2 # 若是 x y 是动态的参数,则利用下面的方法 [root@NEO scripts]# vim show_args.sh [root@NEO scripts]# cat show_args.sh #!/bin/bash # desc: # author: neo # time: # version: x=$1 # 改为 $1 和 $2 y=$2 echo $x $y [root@NEO scripts]# sh show_args.sh 10 20 # 传参10和20;10传给$1 ,20传给 $2 10 20 # read 可以从命令行中读取内容放到变量中 (交互式的) [root@NEO scripts]# read -p "input x y:" x y input x y:10 20 [root@NEO scripts]# echo $x 10 [root@NEO scripts]# echo $y 20 [root@NEO scripts]# [root@NEO scripts]# vim show_args.sh [root@NEO scripts]# cat show_args.sh #!/bin/bash # desc: # author: neo # time: # version: # x=$1 # y=$2 read -p "input x y:" x y echo $x $y [root@NEO scripts]# sh show_args.sh input x y:30 40 30 40 [root@NEO scripts]#
条件表达式: 格式:[<测试表达式>] 先敲一对 [] ,而后退格输入2个空格 [ ],最后再回退一个空格开始输入,即 [] 两端要各有一个空格,如: [ -f /etc/hosts ] 判断文件: -f ---> 文件是否存在 -d ---> 目录是否存在 0 存在,1 不存在 判断整数: 等于 equal ---> -eq 不等于 not equal ---> -ne 大于 greater than ---> -gt 大于等于 greater euqal ---> -ge 小于 less than ---> -lt 小于等于 less euqal ---> -le 简单案例 # Shell编程之测试表达式 --- 中括号 # [] 表示判断或测试 [root@NEO scripts]# [ -f /root/alex.oldboy.txt ] # 判断 /root/alex.oldboy.txt 这个文件是否存在 [root@NEO scripts]# echo $? 1 # 1 表示 [ -f /root/alex.oldboy.txt ] 查找的文件不存在, 0 表示存在 [root@NEO scripts]# [ -f /oldboy/oldboy.txt ] [root@NEO scripts]# echo $? 0 [root@NEO scripts]# [ -d /root ] # 判断 /root 这个目录是否存在; -d 判断目录是否存在 , -f 判断文件是否存在 [root@NEO scripts]# echo $? 0 # 判断整数: [root@NEO scripts]# [ 1 -eq 1 ] [root@NEO scripts]# echo $? 0 # 判断整数的简单案例:判断命令行参数个数等于2 [root@NEO scripts]# sh ./args.sh [root@NEO scripts]# sh ./args.sh a b arg number is 2 [root@NEO scripts]# # 若是 /oldboy 目录不存在则建立 [root@NEO ~]# [ -d /oldboy ] || mkdir -p /oldboy/ # 命令1 || 命令2 ---> || 表示 命令1不成立 则执行 命令2 # 若是 /root/oldboy.txt 存在则提示文件已经存在 [root@NEO ~]# [ -f /oldboy/oldboy.txt ] && echo file exists file exists # Shell编程之 if 判断 # 单分支条件语句: # 语法: if [ 条件 ];then 命令 fi # [] 中括号两端要有两个空格 # 案例:输入2个字,比较大小 # 语法: # if 单分支: [root@NEO scripts]# vim compare.sh [root@NEO scripts]# cat compare.sh #!/bin/bash # desc: # author: neo # time: 20190418 # version: 1.0 num1=$1 num2=$2 if [ $num1 -gt $num2 ];then echo $num1 greater than $num2 fi [root@NEO scripts]# sh compare.sh greater than [root@NEO scripts]# sh compare.sh 10 20 [root@NEO scripts]# sh compare.sh 20 10 20 greater than 10 [root@NEO scripts]# # if 双分支: [root@NEO scripts]# cat compare.sh #!/bin/bash # desc: # author: neo # time: 20190418 # version: 1.0 num1=$1 num2=$2 if [ $num1 -gt $num2 ];then echo $num1 greater than $num2 else echo $num1 less equal $num2 fi [root@NEO scripts]# sh ./compare.sh 10 20 10 less equal 20 [root@NEO scripts]# sh ./compare.sh 20 10 20 greater than 10 [root@NEO scripts]# sh ./compare.sh 20 10 1 3 2 5 7 # 不足之处:后4个参数无用 20 greater than 10 [root@NEO scripts]# sh ./compare.sh 20 ./compare.sh: line 9: [: 20: unary operator expected 20 less equal [root@NEO scripts]# # 参数必须是2个 [root@NEO scripts]# cat compare.sh #!/bin/bash # desc: # author: neo # time: 20190418 # version: 1.0 num1=$1 num2=$2 if [ $# -ne 2 ];then echo "Useage:please input 2 numbers:num1 num2" exit # 退出程序 fi if [ $num1 -gt $num2 ];then echo $num1 greater than $num2 else echo $num1 less equal $num2 fi [root@NEO scripts]# sh compare.sh 10 Useage:please input 2 numbers:num1 num2 [root@NEO scripts]# sh compare.sh 10 20 30 Useage:please input 2 numbers:num1 num2 [root@NEO scripts]# # if 多分支: [root@NEO scripts]# cat compare.sh #!/bin/bash # desc: # author: neo # time: 20190418 # version: 1.0 num1=$1 num2=$2 if [ $# -ne 2 ];then echo "Useage:please input 2 numbers:num1 num2" exit fi if [ $num1 -gt $num2 ];then echo $num1 greater than $num2 elif [ $num1 -lt $num2 ];then echo $num1 less equal $num2 else echo $num1 equal to $num2 fi [root@NEO scripts]# # shell 不太擅长小数
# for 循环语句: # 格式: for 变量名字 in 列表 do 命令 done [root@NEO scripts]# for num in 1 2 3 4 5 > do > echo "the $num number is:"$num > done the 1 number is:1 the 2 number is:2 the 3 number is:3 the 4 number is:4 the 5 number is:5 [root@NEO scripts]# # 优化linux开机启动项目,只保留 crond,sshd,network,rsyslog,sysstat ,其余的都关闭 # 思路: chkconfig 服务 off # 第一步:先排除上面的那几个服务 [root@NEO scripts]# chkconfig |egrep "crond|sshd|network|rsyslog|sysstat" -v # 第二步:取出全部的服务名 [root@NEO scripts]# chkconfig |egrep "crond|sshd|network|rsyslog|sysstat" -v|awk '{print $1}' # for 循环遍历关闭 [root@NEO scripts]# for service in `chkconfig |egrep "crond|sshd|network|rsyslog|sysstat" -v|awk '{print $1}'` > do > echo chkconfig $service off # echo 为了测试 > done