Shell
shell定义
Shell 是一种程序设计语言,他有变量,关键字,各种控制语句和自己的语法结构,
可以编写功能很强,代码简短的程序#! Shebang 定义解释器#!/usr/bin/python#!/bin/bash
shell分类
/bin/sh/bin/bash/sbin/nologin/usr/bin/sh/usr/bin/bash/usr/bin/nologin默认shell : bash shell查看当前使用的shellecho $SHELLshell的切换vim /etc/passwd 编辑登录shell
bash配置文件
开机执行/etc/rc.loacl全局配置文件登录执行/etc/profile/etc/profile.d/*.sh/etc/bashrc个人配置文件~/.bash_profile -----离开时执行~/.bashrc登出加载的配置文件~/.bash_logout登陆式shell加载配置文件的过程~/.bash_profile ---> ~/.bashrc ---> /etc/bashrc ---> /etc/profile ---> /etc/profile.d/*.sh非登录式shell加载配置文件过程~/.bashrc ---> /etc/bashrc ---> /etc/profile.d/*.shprofile类的文件 : 设定环境变量运行命令或脚本bashrc类的文件定义命令别名
通配符
Shell 通配符* ? [] {}* : 匹配所有的字符? : 匹配任意一个字符[] : 匹配[]中的任意一个字符[!0-9] : 匹配除了[]中的任意字符不能是数字{} : 匹配{}中其中一个字符串
Shell脚本规范
定义解释器#!/bin/bash#! Shebang执行方式sh bash 创建子shell执行脚本,脚本的环境变量和环境设置不会影响当前环境. source 父shell亲自执行脚本,脚本可以改变当前的环境设置和变量./ 需要执行权限脚本测试sh -x 显示所有的变量值sh -n 检查脚本的语法是否有错误 sh 和 source的区别:sh:当使用sh来执行脚本时,它会创建一个新的子进程来执行脚本,
并且脚本中的变量和环境设置通常不会影响当前的shell环境source:使用source或.来执行脚本文件时,脚本中的命令会在当前Shell环境中执行,
并且脚本可以修改当前Shell的变量和环境设置。
shell变量
预定义变量
$? 最后一次执行的命令的返回状态$$ 当前进程的进程号$! 后台运行的最后一个进程的进程号$# 位置参数的数量$@ 所有位置参数的内容$* 所有位置参数的内容
自定义变量
自定义变量定义 : 变量名称=值变量名称 : 只能有字母,数字.下划线组成,不能以数字开头,-波折号=赋值符号前后不能有空格 引用变量 : $变量名 或者 ${变量名}查看变量 :echo $变量名 set (所有变量 : 包括自定义变量)env (环境变量)取消变量 :unset 变量名 仅在当前shell中有效作用范围 :仅在当前shell中生效
环境变量
环境变量shell在开始执行时已经定义好的env 查看所有的环境变量set 查看所有变量环境变量拥有可继承性 : export之后就拥有继承性export 查看变量export 变量名=变量值 env常用的环境变量USER UID HOME HOSTNAME PWD PS1 PATH PATH : 存储所有命令所在的路径
变量运算
变量运算算式运算符+ - * / %取余 () 运算方式$(()) $[] expr 运算符号左右要有空格 '*'或\*$RANDOM 随机数eg:$(())# echo $(( 5+2-(3*2)/5 )) 6$[]# echo $[ 5 + 2 - (3*2)/5 ]6 expr# expr 5 + 3浮点运算bash不能做小数计算:需要bc命令转换"scale=10;3/10" | bc -lscale : 精确值bc -l : 数学库
变量的引用
转义 : \一个字符被引用时,其特殊含义被禁止"" 弱引'' 强引\n 换行 \t 制表符 \a 蜂鸣read -p 打印提示信息-t 超时时间-s 取消回显
变量替换
${a:-xx} 若a为空或未设置,则用xx代替a进行替换,a的值不变 read -p "请输入你要符的值:" numecho ${num:-hello}echo $num[root@localhost ~]# sh test.sh 请输入你要符的值:111[root@localhost ~]# sh test.sh 请输入你要符的值:hello[root@localhost ~]# ${a:=xx} 若a为空或未设置,则用xx代替a进行替换,a的值改变为xx read -p "请输入你要符的值:" numecho ${num:=hello}echo $num[root@localhost ~]# sh test.sh 请输入你要符的值:111[root@localhost ~]# sh test.sh 请输入你要符的值:hellohello[root@localhost ~]# ${a:+xx} 若a设置了,则用xx代替a进行替换,a的值不变,a没设值,则为空read -p "请输入你要符的值:" numecho ${num:+hello}echo $num[root@localhost ~]# sh test.sh 请输入你要符的值:1hello1[root@localhost ~]# sh test.sh 请输入你要符的值:[root@localhost ~]# ${a:?xx} 若a为空或未设置,则xx作为标准错误打印出来,这可用来检查变量是否正确设置
匹配截取
${变量#关键词} 变量内容从左边开始符合关键词则将符合的最短数据切除${a#*.} 切掉首个.左边的所有内容z${变量##关键词} 变量内容从左边开始符合关键词则将符合的最长数据切除${a##*.} 切掉最后.左边的所有内容${变量%关键词} 变量内容从右边开始符合关键词则将符合的最短数据切除${a%.*} 切掉首个.右边的所有内容${变量%%关键词} 变量内容从右边开始的数据符合关键词则将符合的最长数据切除${a%%.*} 切掉最后.右边的所有内容${变量/旧字符串/新字符串/} 变量内容符合旧字符串则将第一个旧字符串替换位新字符串${变量//旧字符串/新字符串/} 变量内容符合旧字符串则将全部字符串替换位新字符串tr -d "."echo $a | tr "." "/"
shell流程控制
测试test 条件条件为真返回 0,条件为假返回 1[ 条件 ]test 能够理解3种类型的表达式 1.文件测试2.字符串比较3.数字比较字符串-n STRING# -n 字符串长度不为零-z STRING# -z 字符串长度为0STRING1 = STRING2# = 判断两个字符串是否一样STRING1 != STRING2# != 判断两个字符串是否不一样数字-eq 等于 -ne 不等于 -ge 大于等于 -le 小于等于 -gt 大于 -lt 小于 文件test-f 存在且是普通文件 # 重要-d 存在且是目录 #-h 存在且是符号链接 -b 块设备-c 字符设备-e 文件存在 #-a && 逻辑与 and 两端的条件都可以成立-o || 逻辑或 or 两端的条件有一段成立就行 if语句格式if[判断条件];thenelifelseifcase语句格式case $变量 in模式1);;模式2);;*);;esac
for语句
for i in {范围}for关键词 i变量名 in关键词 取值范围格式(空格,制表符 换行)do循环体done99乘法表for i in {1..9}dofor j in `seq $i`doecho -ne "${j}x${i}=$[$i * $j]\t"doneecho ""donefor i in `cat a.txt`do循环体 echo '$i'done
while语句
方式一:while 条件while 关键字 条件 [ $1 -lt 10 ] ,while循环,条件为真的情况下,会循环do循环体done方式二:将文本内容交给while循环,以行为单位处理,最后一行需要换行(windos创建的文件)while read linedo循环体done < /文本路径方式三 : 将文本内容交给while循环cat aaa.txt | while read linedo循环体done eg : yum -y install `cat a.txt` | while read linedoecho "anzhuagn $line"done
until语句
until 条件 # 当后面的条件表达式,为假的时候进行循环,当他为真了就停止循环了。do循环体doneeg : a=0until [ $a -gt 10 ]dolet a++echo $adone
循环控制
shift将位置参数左移一位break结束退出本次循环continue在循环中不执行continue下面的代码,转而进入下一轮循环exit退出脚本
函数
function 完成特定功能的代码片段函数必须先定义才能使用优点:避免重复的代码unset 函数名 ---->取消函数eg: function_name () {list of commands}函数名 function_name,使用它从其他地方在脚本调用。
tput setab [1-7]---设置背景颜色tput setaf [1-7]----设置字体颜色tput sgr0 ---- 重置颜色
属组
books=( linux shell awk sed ) 取出所有的元素echo ${books[@]}取出所有的索引echo ${!books[@]}取出索引的个数echo ${#books[@]}在数组中增加元素books[4]="mysql"修改数组中的某个值books[0]="grep"删除数组中的某个元素unset books[0]
关联数组需要提前声明
declare -A mymy=([name]=newrain [sex]=man [age]=26)echo ${my[name]}==>newrainecho ${my[age]}==>26echo ${!my[@]}
shell属组中"*"和"@"区别
关于在shell脚本中数组变量中 “*”跟 “@” 区别“*”当变量加上“” 会当成一串字符串处理. “@”变量加上“” 依然当做数组处理. 在没有加上“” 的情况下 效果是等效的.
基本正则表达式:(grep支持)
元字符示例 功能^ 行首定位符^love $ 行尾定位符love$ . 匹配单个字符l..e * 匹配前导符0到多次 全部匹配 grep "o*" /etc/passwdab*love .* 匹配任意多个字符 (贪婪匹配[] 匹配方括号中任意一个字符[lL]ove[ - ] 匹配指定范围内的一个字符[a-z0-9]ove [^] 匹配不在指定组里的字符[^a-z0-9]ove \ 用来转义元字符love\. \< 词首定位符 #由数字或字母组成的\<love\> 词尾定位符love\>\(\) 匹配后的标签 # 在vim中测试:%s@\(张三\) \(李四\) \(王五\)@ \3 \1 \2@g
拓展正则表达式:(grep -E,grep -P,egrep)
= 等于 != 不等于 =~ 匹配扩展正则表达式元字符+ 匹配一个或多个前导字符[a-z]+ove? 匹配零个或一个前导字符 lo?ve"r.*t" 贪婪匹配-P "r.*?" 非贪婪匹配a|b 匹配a或blove|hate() 组字符loveable|rslove(able|rs) ov+ ov+ (ov)+ (oo)+ 两个oo出现一次或者多个(..)(..)\1\2 标签匹配字符 #(love)able\1erx{m} 字符x重复m次o{5}o{,3} 字符最多出现3次x{m,} 字符x重复至少m次o{5,} 字符最少出现5次x{m,n} 字符x重复m到n次o{5,10}grep -E "o{3}" /etc/passwdgrep -P "\s" /etc/passwd 空格grep -P "\d" /etc/passwd 数字
shell里面的多行注释:
shell里面的多行注释:<!........!
grep
grep -E 支持拓展正则表达式grep -E "o{3}" /etc/passwdgrep -P 支持拓展正则表达式grep -P "\s" /etc/passwd 空格grep -P "\d" /etc/passwd 数字grep -v :取反ps -ef | grep nginx | grep -v grepgrep -i : 忽略大小写grep -i "ROOT" /etc/passwdgrep -c :统计次数grep -i -c"ROOT" /etc/passwdgrep -o :只显示匹配到的内容grep -o "root" /etc/passwdgrep -F|fgrep 精准匹配,不支持任何的特殊字符fgrep "[shell]" /opt/passwd ==>看到什么过滤什么 不用考虑正则表达式grep -r 递归过滤
sed
前面两个斜杠中是要匹配的内容,可以使用正则,后面两个斜杠中间,是要替换的内容,是纯文本将表准输出| sed 参数 模式sed 's/要替换的内容/替换后的内容/' file.txtsed -f 指定一个脚本文件来处理文档,需求多的时候sed -n 阻止输入行输出sed -r 可以匹配到扩展正则sed -p 打印
在文件中匹配到的删除:
sed '1d' file.txt 删除文件第一行sed '1,2d' file.txt 删除文件的第一行到第二行sed '2,$d' file.txt 删除第二行到最后一行sed '/root/d' file.txt 匹配到root行,删除该行sed '/关键字/,$d' 删除关键字所在的行到最后一行的内容sed '1,/关键字/d' 删除第一行到关键字所在的行sed '/关键字/,/下一个关键字/d' 删除两个关键字所在行以及中间的行sed '/root/,2d' file.txt 匹配到root行,到第二行,删除sed '/^$/d' file.txt 删除空行sed '/#.*/d' file.txt 删除注释行sed '1~2d' file.txt 删除奇数行sed '0~2d' file.txt 删除偶数行sed '3d;10d' file.txt 删除第三行和第十行
在文件中匹配到的部分修改文件:
sed -i 's/odler/new/g' "-i"修改后的数据会替换原文件,"-g"全局替换sed -i.bak 's/older/new/' 在替换前会生成一个备份文件
在文件中匹配到的部分前后加上一行:
sed '/^bin/a\hello nihao/' passwd # 在匹配到开头为bin的行下一行插入内容sed '/^bin/i\hello nihao/' passwd # 在匹配到开头为bin的行上一行插入内容
案例
修改ssh服务配置文件1、拒绝root用户远程登录#PermitRootLogin yesPermitRootLogin nosed -r 's/#PermitRootLogin.*/PermitRootLogin=no/g'2、修改端口为22 2222#Port 22Port 2222/#Port 22/a\Port 22223、修改dns反解析为no #UseDNS yesUseDNS no/#UseDNS/a\UseDNS=no/#UseDNS/d2.修改nginx的配置文件1、修改端口为88 listen 80;listen [::] 80;sed -r 's/Listen\s+[0-9]{2}\;/listen 88;/i' /etc/nginx/nginx.conf2.修改网站根目录为/opt/websed -r 's/^[^#]\s+root\s+\/usr\/share\/nginx\/html\;/ root \/opt\/web;/' /etc/nginx/nginx.confsed -r s///root /usr/share/nginx/html;# root /usr/share/nginx/html;/^[^#]\s+root\s+\/usr\/share\/nginx\/html\;/root \/opt\/web;/3.修改selinux的配置将selinux设置为永久关闭sed -r 's/^SELINUX=.*/SELINUX=hello/' /etc/selinux/config
awk
切割字段awk 参数 模式 文件将标准输出|awk 参数 模式awk BEGIN{开始处理数据前的操作,只执行一次}{处理数据的操作,文本有多少行执行多少次}END{数据处理完成以后的操作,执行一次}参数-F 指定分隔符FS 指定输入字段分隔符 空格和tabOFS 指定输出字段分隔符 空格和tabRS 指定输入记录分隔符 换行ORS 指定输出记录分隔符 换行NR 行号NF 列数FNR 不同文件各自显示行号