shell脚本

先设置脚本格式,tab键自动缩进4格

vim ~/.vimrc

autocmd FileType sh set ai ts=4

变量

1.自定义变量

unset a 或 a=            //把变量置为空

set        //查看所有变量

2.环境变量:系统定义好的变量

USER UID HOME SHELL HOSTNAME PWD

PS1 一级提示符 

PS2 二级提示符

PATH 存储了命令的路径

/etc/profile    永久变量配置文件(所有用户)

~/.bash_profile    (仅对单个用户生效)

env   //查看所有环境变量

3.位置变量与预定义变量

$1 第一个参数

$2 第二个参数

$3 第三个参数

$0 脚本的名称

$# 所有参数的个数

$* 所有参数

$$ 当前进程的进程号

$? 上一个程序的返回状态码,0是成功,非0是失败

变量的扩展应用

1.三种引号对变量赋值的影响

" "使用双引号可以界定一个完整字符串,允许扩展以$引用其他变量。

' '界定范围,屏蔽特殊符号,禁用扩展,即便$也视为普通字符。

` `或$()  将命令的执行结果赋值到变量值

2.使用read命令从键盘读取变量值

read基本用法:

read -p "提示语" i      //结合-p选项给出友好提示,执行后从会等待并接受用户输入,并赋值给变量i

3.stty终端显示控制

将回显功能关闭(stty -echo),将回显功能恢复(stty echo)。

4.使用export发布全局变量

默认情况下,自定义的变量为局部变量,只在当前Shell环境中有效,而在子Shell环境中无法直接使用。

export  变量名    //发布全局变量,可在子环境中使用

Shell中的数值运算

整数运算工具

1.expr命令

模板:expr  整数(变量)   运算符号     整数(变量)

参与运算的整数值与运算操作符之间需要以空格分开,引用变量时必须加$符号。

+    #加法

-     #减法

\*    #乘法,操作符应添加\转义

/     #除法,仅保留整除结果

%   #求模

2.$[]或$(())表达式

乘法操作*无需转义,运算符两侧可以无空格;引用变量可省略 $ 符号;计算结果替换表达式本身,可结合echo命令输出。

x=1000

echo $[x*77]

3.let命令

expr或$[]、$(())方式只进行运算,并不会改变变量的值;而let命令可以直接对变量值做运算再保存新的值。

let a++         #变量a加1

let a--           #变量a减1

let a+=10     #变量a加10

let a-=10      #变量a减10

let a*=2        #变量a乘以2

let a/=2         #变量a除以2

let a%=3       #变量a除以3取余数

小数运算工具

1.bc交互式运算

bc    #先执行bc命令进入交互环境,然后再输入需要计算的表达式。

2.bc非交互式运算

echo "1.1+1" | bc  

echo "scale=2;10/3" | bc      #scale可以定义结果是小数点后多少位

条件测试

使用“test 表达式”或者[ 表达式 ]都可以,注意空格不要缺少。

条件测试操作本身不显示出任何信息。所以可以在测试后查看变量$?的值来做出判断。

1.字符串

==   判断两边是否相等                 

!=    判断两边是否不等

-z    判断变量是否为空

! -z或-n   判断变量是否非空

2.逻辑组合

&&  与               A&&B      当A成功时,会执行B(两个成功才算真)

||     或               A||B         当A失败时,会执行B(有一个成功就算真)

3.整数值比较

-eq  是否相等

-ne   是否不相等

-gt    大于

-ge   大于等于

-lt      小于

-le     小于等于

4.识别文件/目录的状态

-e  判断对象是否存在,不管是目录还是文件

-f   判断对象是否为文件,存在且是文件

-d  判断对象是否为目录,存在且是目录

-r   判断当前用户对文件是否有读权限,对root无效

-w  判断当前用户对文件是否有写权限,对root无效

-x   判断当前用户对文件是否有x权限

if选择结构

1.单分支

if 条件测试;then

指令

fi

2.双分支

if 条件测试;then

指令

else

指令

fi

3.多分支

if 条件测试;then

指令

elif 条件测试;then

指令

...

else

指令

fi

for循环结构

for 变量名 in 值1 值2 值3 ...(有几个值,指令就执行几次)     #{1..100}   循环100次,但不支持变量;a=100,"seq $a"     如果循环次数是通过变量决定可以用seq指令

do

指令

done

for ((初值;条件;步长))     #C语言风格的for循环格式

do

指令

done

while循环结构

while 条件测试         #根据条件的结果决定是否要执行任务,条件测试成功的话就执行,如果失败立刻结束循环                                    #: 冒号可以表示条件为真,例while :

do

指令

done

循环控制

中断及退出

exit  结束循环及整个脚本

break  结束循环,继续循环之后的任务

continue  结束本次循环,进入下一次循环

case分支

case分支属于匹配执行的方式,它针对指定的变量预先设置一个可能的取值,判断该变量的实际取值是否与预设的某一个值相匹配,如果匹配上了,就执行相应的一组操作,如果没有任何值能够匹配,就执行预先设置的默认操作。

case 变量 in

模式1)        #可以使用 | 分隔预设多个值

命令;;

模式2)

命令;;

*)

默认命令

esac

Shell函数

函数:将一些重复使用的命令,定义为公共的语句块。

return是跳出函数(直接结束函数)

格式1:

function 函数名 {

命令

}

格式2:

函数名(){

命令

}

函数的调用

直接使用“函数名”的形式调用,如果该函数能够处理位置参数,则可以使用“函数名 参数1 参数2 .. ..”的形式调用。注意:函数的定义语句必须出现在调用之前,否则无法执行。

字符串处理

字符串的截取

使用 ${}表达式

格式:${变量名:起始位置:长度}

一个随机密码的案例,首先实现1个字符的随机产生。

x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

n=$[RANDOM%62]                 #得到0~61随机数存在变量n中

p=$[x:n:1]                                #通过截取,将1个随机字符赋值给变量p

字符串的替换

只替换第1个子串

格式:${变量名/old/new}

替换全部子串

格式:${变量名//old/new}

删除

格式:${变量名//旧/ }

字符串的匹配删除

例如有个变量a=abcdabcd

1.从左向右,最短匹配删除

格式:${变量名#*关键词}

删除从左侧第1个字符到最近的关键词

例:echo ${a#*c}

结果为:dabcd

2.从左向右,最长匹配删除

格式:${变量名##*关键词}

删除从左侧第1个字符到最远的关键词

例:echo ${a##*c}

结果为:d

3.从右向左,最短匹配删除

格式:${变量名%关键词*}

删除从右侧最后1个字符到往左最近的关键词

例:echo ${a%c*}

结果为:abcdab

4.从右向左,最长匹配删除

格式:${变量名%%关键词*}

删除从右侧最后1个字符到往左最远的关键词

例:echo ${a%%c*}

结果为:ab

字符串初值的处理

定义变量初值(备用值)

${变量名:-初值}      #若变量已存在且非空,则返回变量原本的值;若变量为空,则自动调用初值

正则表达式

基本正则列表

^     匹配行首

$     匹配行尾

[ ]     集合,匹配集合中的任意单个字符

[^]     对集合取反

.       匹配任意单个字符

*       匹配前一个字符任意次数[*不允许单独使用]

\{n,m\}    匹配前一个字符n到m次

\{n,\}       匹配前一个字符n次及以上

\{n\}        匹配前一个字符n次

\(\)          组合为整体,保留

扩展正则列表

+   至少匹配一次

?   最多匹配一次(0次或1次)

{n,m}    匹配前一个字符n到m次

( )    组合为整体,保留

|      或者

\b    单词边界           例:\b单词\b

grep -E = egrep     #允许使用扩展准则

grep -q   #不显示所有常规输出(黑洞)

perl 正则

grep -P  "\w"      #匹配字母数字下划线

grep -P  "\d"      #匹配数字=[0-9]

grep -P  "\s"      #匹配空白(可以匹配空格,tab键)

sed工具

格式:sed  [选项]  "条件指令"  文件

  • 条件可以是行号或者/正则/,没有条件时默认为所有行都执行指令
  • 指令可以是p输出、d删除、s替换、c替换(整行)、i在前面插入一行、a在后面插入一行

sed命令的常用选项如下:

sed -i   #修改文件内容

sed -n  #屏蔽默认输出

sed -r   #支持扩展正则

使用sed

1)行号案例

sed -n '2,4p' 文件                #输出2~4行

sed -n '2p;4p' 文件                #输出第2行与第4行

sed -n '3,+1p' 文件                #输出第3行以及后面1行

sed -n '1~2p' 文件           #输出奇数行

2)使用正则当条件

sed -n '/^root/p' 文件            #输出以root开头的行

sed -n '/root/p' 文件                #输出包含root的行

sed -nr '/^root|^bin/p' 文件        #输出以root开头的行或bin开头的行,|是扩展正则,需要r选项

3)特殊用法

sed -n '1!p' 文件                    #输出除了第1行的内容,!是取反

sed -n '$p' 文件                    #输出最后一行

sed -n '=' 文件                    #输出行号,如果是$=就是最后一行的行号

sed工具的d、s、c、i、a操作指令

1)d指令删除

 sed '3,5d' 文件            #删除第3~5行

sed '/xml/d' 文件            #删除所有包含xml的行

sed '/xml/!d' 文件         #删除不包含xml的行,!符号表示取反

sed '/^install/d' 文件    #删除以install开头的行

sed '$d' 文件                #删除文件的最后一行

sed '/^$/d' 文件             #删除所有空行

2)s指令替换基本功能(s/旧内容/新内容/选项)

sed 's/2017/6666/' 文件            #把所有行的第1个2017替换成6666

sed 's/2017/6666/2' 文件        #把所有行的第2个2017替换成6666

sed '1s/2017/6666/' 文件        #把第1行的第1个2017替换成6666

sed '3s/2017/6666/3' 文件        #把第3行的第3个2017替换成6666

sed 's/2017/6666/g' 文件         #所有行的所有个2017都替换

sed '/2024/s/2017/6666/g' 文件    #找含有2024的行,将里面的所有2017替换成6666

如果想把 /bin/bash 替换成 /sbin/sh 怎么操作?

sed 's/\/bin\/bash/\/sbin\/sh/' 文件    #使用转义符号可以成功,但不方便

sed 's!/bin/bash!/sbin/sh!' 文件        #最佳方案,更改s的替换符

sed 's(/bin/bash(/sbin/sh(' 文件       #替换符号可以用键盘上大部分字符

sed -r 's/([0-9]+)(\s+)([a-z]+)/\3\2\1/' abc.txt    #使用替换功能更改文本列,此处小括号相当于保留(复制),\1相当于粘贴之前第1个小括号里的内容

3)c指令替换整行(c 新内容)

sed 'c 666' 文件    #所有行都替换成666

sed '1c 666' 文件    #替换第1行为666

sed  '/^HISTSIZE/c HISTSIZE=2000' /etc/profile    #替换以HISTSIZE开头的行为HISTSIZE=2000

4)i指令在前面插入一行(i 插入的内容)

sed 'i 666' 文件     #所有行的上面添加666

sed '5i 666' 文件    #第5行的上面添加666

sed '$i 666' 文件    #最后1行的上面添加666

sed  '/^export/i HISTTIMEFORMAT="%F %T "' /etc/profile     #在以export开头的行的上面插入HISTTIMEFORMAT="%F %T "

5)a指令在后面插入一行(a 插入的内容)

sed 'a 666' 文件       #所有行的下面追加666

sed '1a 666' 文件      #第1行的下面追加666

sed '/^bin/a 666' 文件     #在以bin开头的行的下面追加666

awk提取文本

awk的基本用法

格式1:awk [选项] '[条件]{指令}' 文件

格式2:前置指令 | awk [选项] '[条件]{指令}'

其中,print 是最常用的编辑指令;若有多条编辑指令,可用分号分隔。

awk过滤数据时支持仅打印某一列,如第2列、第5列等。

处理文本时,默认将空格、制表符作为分隔符。

条件可以用/ /的方式,与sed类似。

awk常用内置变量

$0 文本当前行的全部内容

$1 文本的第1列

$2 文本的第2列,以此类推

NR 文件当前行的行号

NF 文件当前行的列数(有几列)

awk常用的选项

awk -F  ...      #可指定分隔符

awk -F [:/]   ...     #awk还可以识别多种单个的字符,比如以“:”或“/”分隔

awk处理的时机

awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行之后做一些总结性质的工作。

格式为:awk [选项] 'BEGIN{指令} {指令} END{指令}' 文件

  • BEGIN{ } 行前处理,读取文件内容前执行,指令执行1次。
  • { } 逐行处理,读取文件过程中执行,指令执行n次。
  • END{ } 行后处理,读取文件结束后执行,指令执行1次。

awk处理条件

1.使用正则设置条件

/正则/ ~ 包含 !~ 不包含

awk  '$6~/bin/{print}' 文件       #输出第6列包含bin的行

awk  '$6!~/bin/{print}' 文件      #输出第6列不包含bin的行

2.使用数值/字符串比较设置条件

比较符号:==(等于)   !=(不等于)  >(大于)  >=(大于等于) <(小于)  <=(小于等于)

awk  '$3<3{print}' 文件            #输出第3列小于3的行

awk  '$3<=3{print}' 文件        #输出第3列小于等于3的行

awk  'NR==2{print}' 文件        #输出第2行

awk  'NR>2{print}' 文件          #输出行号大于2的行

3.逻辑测试条件

|| 或

&& 并且

awk  'NR>=3&&NR<=5{print}' 文件            #找行号是3~5行

awk  'NR==2||NR==4{print}' 文件            #找行号是2或者4的行

awk  'NR==2||NR==40{print}' 文件         #如果只有一个条件满足就显示一个

4.数学运算

awk 'NR%2==0{print NR,$0}' 文件     #在条件中使用运算,找到将行号除以2余数等于0的行,然后输出该行的行号和所有列,相当于输出偶数行

awk数组

数组是一个可以存储多个值的变量,具体使用的格式如下:

定义数组的格式:数组名[下标]=元素值

调用数组的格式:数组名[下标]

awk 'BEGIN{a[1]=10;a[2]=20;print a[2],a[1]}'          #使用awk测试数组,创建数组a,下标1对应值是10,下标2对应值是20,然后输出下标是2与下标是1的值

数组可以收集信息,但收集完了之后查看确不方便,可以用for循环实现。

for(变量名 in 数组名){print 变量名}        #这个格式可以查看数组的所有下标

awk '{a[$1]++}END{for(i in a){print i,a[i]}}' shu.txt       #使用逐行任务与数组收集文档shu.txt中的信息,然后在END任务中使用for循环显示所有数组a的下标与值

其它

egrep常用选项:

egrep -i       #忽略字母大小写

egrep -v      #条件取反

egrep -c      #统计匹配的行数

egrep -q      #静默、无任何输出;多用于检测

egrep -n      #显示出匹配结果所在的行号

egrep --color     #标红显示匹配字符

ss命令可以查看系统中启动的端口信息,该命令常用选项如下:

-n以数字格式显示端口号

-t显示TCP连接的端口

-u显示UDP连接的端口

-l显示服务正在监听的端口信息,如httpd启动后,会一直监听80端口

-p显示监听端口的服务名称是什么(也就是程序名称)

例如:ss -ntulp | grep nginx

输出重定向

> 重定向标准输出

2> 重定向错误输出

&> 重定向所有输出

>> 将输出以追加的方式重定向

输入重定向

< 符号,输入重定向,可以在后面需要跟文件名,这样让程序不再从键盘读取数据,而是从文件中读取数据。

<< 符号也称Here Document,代表你需要的内容在这里,某指令导入字符串时使用,而无需文件

例如:

mail -s test root << EOF

hello

test mail~

EOF

strings  查看动态文件 

取随机十位字符:tr -cd '_a-zA-Z0-9' < /dev/urandom | head -c 10

sort排序:

sort -nr -k 2      #n表示用数字排序,r表示降序排序,k 2表示排序每行的第2列,默认排序是升序

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值