tsumiki

导航

shell基础

一.shell脚本

在 /etc/shells 中可以找到当前系统支持的shell脚本种类

 

 脚本用途

将简单的命令组合完成复杂的工作,自动化执行命令,提高工作效率

减少手工命令的重复输入,一定程度上避免人为错误

将软件或应用的安装及配置实现标准化

用于实现日常性的,重复性的运维工作,如:文件打包压缩备份,监控系统运行状态并实现告警等

 

脚本构成

脚本申明(解释器):第一行开头“#!/bin/bash”,表示此行以下的代码语句是通过/bin/bash程序来解释执行。#!/bin/bash为默认的解释器还有其他类型的解释器,#!/bin/python #!/bin/expect

注释信息:以#开头的语句表示为注释信息

可执行语句、命令:比如echo命令用于输出" "之间的字符串

 

脚本执行逻辑和方式

相对绝对路径

相对路径 

./cipan.sh    需要执行权限! chmod  777 cipan.sh

绝对路径

~/cipan.sh
 

指定解释器执行

bash cipan.sh

 

source 和 ‘.’ 启动 ,但是会在启动一个bash进程,影响当前环境

 

脚本可能发生的错误

1.命令错误:默认后续的命令还会继续执行,用bash -x进行检查

2.语法错误:可以使用bash -n 检查错误,错误的行数不一定准确

3.逻辑错误:只能自己去筛查

 

二.重定向与管道符

1)重定向

  类型              设备文件          文件描述编号          默认设备

标准输入        /dev/stdin           0                              键盘

标准输出        /dev/stdout         1                             显示器

标准错误输出 /dev/stderr         2                             显示器

 

标准输入:从该设备接收用户输入的数据

标准输出:通过该设备向用户输出的数据

标准错误:通过该设备报告执行出错的信息

重定向的意思就是,不通过标准输出到屏幕上,输出到自己指定的位置

类型                                      操作符                                用途
重定向输入                              <                          从指定的文件读取数据,而不是从键盘输入
重定向输出                             1>                         将输出结果保存到指定的文件(覆盖原有内容)
                                               >>                         将输出结果追加到指定的文件尾部
标准错误输出                         2>                         将错误信息保存到指定的文件(覆盖原有内容)
                                              2>>                        标准错误输出结果追加到指定的文件尾部
混合输出           &>(无论对错都可以重定向)   将标准输出、标准错误的内容保存到同一个文件中

2)多行重定向

Here Document 概述 使用 I/O 重定向的方式将命令列表提供给交互式程序或命令,比如 ftp、cat 或 read 命令。 HereDocument是标准输入的一种替代品, 可以帮助脚本开发人员不必使用临时文件来构建输入信息, 而是直接就地生产出一个文件并用作命令的标准输入。

EOF

—————————————————————————————————————————————————————————————————————————————————

—————————————————————————————————————————————————————————————————————————————————

 ————————————————————————————————————————————————————————————————————————————————

三.变量

1)常见shell变量类型

自定义变量:由用户自己定义,修改和使用

环境变量:由系统维护,用于设置工作环境

只读变量:只可以读取不可以更改

位置变量:通过命令行给脚本传递参数

预定义变量:Bash中内置的一类变量,不能修改 有些规定好的变量 放在那里让你使用

 2)变量命名要求

区分大小写

不能使程序中的保留字和内置变量:如:if, for,hostname 命令

只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反

不要使用内置的变量,使用英文尽量使用词义通俗易懂,PATH

 3)自定义变量

 name='value'

变量名=变量值

直接字串:name='root'

变量引用:name="$USER"

命令引用:name=COMMAND 或者 name=$(COMMAND)

注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除

 

变量引用:

$name

${name}

 

弱引用和强引用

"$name " 弱引用,其中的变量引用会被替换为变量值

'$name ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

 

变量追加值

格式 变量名+=追加值

 

1.赋值时使用双引号(" ")可以直接调用变量

2.赋值时使用单引号(' ')只会被认为是字符 不会调用变量

3.赋值时使用(``反撇在tab上面)命令替换,提取命令执行后的输出结 果 和$( ) 用法相同

4.{}可以分隔变量值

 

read -p

从键盘输入的内容变成变量

 

整数运算

expr和let只能进行整数的运算

格式: expr 变量1 运算符 变量2 [运算符 变量3]

运算符:

加法 +

减法 -

乘法 \ *

除法 /

取余 (取模)%

 

随机数生成

 1-100随机数

 

提取系统信息

 

环境变量

由系统提前创建,用来设置用户的工作环境

可以使用env查看环境变量

需要记住的常用环境变量

$USER 表示用户名称

$HOME 表示用户的宿主目录

$LANG 表示语言和字符集

$PWD 表示当前所在工作目录

$PATH 表示可执行用户程序的默认路径

 

环境变量的全局配置文件:

/etc/profile如果修改此文件会作用于所有用户

~/.bash_profile 用户独立的配置文件,修改这个文件只作用于当前用户 可以用来长期变更或设置环境变量

 

位置变量

求和

 

预定义(状态)变量

系统已经设置好了,直接可以拿来使用,不需要知道为什么,自己死记硬背

$*:表示所有位置参数的内容看成一个整体返回 返回所有

$@:表示所有位置参数的内容分割成n份,每份作为一个独立的个体返回 返回所有

$?:表示前一条命令执行后的返回状态,返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常

$#:表示命令行中位置参数的总个数

$0:表示当前执行的脚本或程序的名称 当前脚本的名字

'$$':当前进程id

$!: 后台任务最后一个id

 

$*是将整个参数名看做一个整体

$@是把每一个参数看成一个整体

 

4.条件语句

1)测试

test测试文件的表达式是否成立

格式1:test 条件表达式

格式2:[ 注意两边需要空格 ]

格式3:[ 操作符 文件或者目录]

 

操作符:

-d:测试是否为目录(Directory)
-e:测试目录或文件是否存在(Exist)
-a:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否有权限执行(eXcute)
-L: 测试是否为软连接文件 属性测试补充:
-s FILE #是否存在且非空
-t fd #fd 文件描述符是否在某终端已经打开
-N FILE #文件自从上一次被读取之后是否被修改过
-O FILE #当前有效用户是否为文件属主
-G FILE #当前有效用户是否为文件属组
 
 
若真,则状态码变量 $? 返回0
若假,则状态码变量 $? 返回1
条件测试命令

 

2)比较整数数值

格式:[ 整数1 操作符 整数2 ] 公式

-eq:第一个数等于(Equal)第二个数

-ne:第一个数不等于(Not Equal)第二个数
-gt:第一个数大于(Greater Than)第二个数
-lt:第一个数小于(Lesser Than)第二个数
-le:第一个数小于或等于(Lesser or Equal)第二个数
-ge:第一个数大于或等于(Greater or Equal)第二个数

3)字符串比较

常见的测试操作符

=:字符串内容相同

!=:字符串内容不同,! 号表示相反的意思

-z:字符串内容为空

-n: 字符是否存在

 

格式:

[ 字符串1 = 字符串2 ] 是否相同

[ 字符串1 != 字符串2 ] 是否不相同

[ -z 字符串 ] 是否为空

[ -n 字符串 ] 字符是否存在

 

4)逻辑测试

格式1:【表达式1】操作符【表达式2】...

格式2:命令1 操作符 命令2 ...

 

常见条件

-a或&&:逻辑与,“而且”的意思全真才为真

-o或||:逻辑或,“或者”的意思一真即为真

!:逻辑否

 

两个命令都为真时

 

5)双中括号

[[ expression ]] 用法:
== 左侧字符串是否和右侧的PATTERN相同
     注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
     注意: 此表达式用于[[ ]]中;扩展的正则表达式

 

(){ }

 (空格CMD1;CMD2;...空格)和 {空格CMD1;CMD2;...;空格} 都可以将多个命令组合在一起,批量执行

 

6)if 语句结构

单分支结构

if 判断条件

then 条件为真的分支代码

fi

 

双分支

if 判断条件

then 条件为真的分支代码

else 条件为假的分支代码

fi

多分支

if 判断条件1

then 条件1

为真的分支代码

 

elif 判断条件2

then

条件2为真的分支代码

 

elif 判断条件3

条件3为真的分支代码

 

then

...

else

以上条件都为假的分支代码

 

fi

 

7)case 结构

 case 变量引用 in

PAT1)

分支1

;;

PAT2)

分支2

;;

...

*) //其他,必须要有的格式 默认分支

;;

 esac

 

8)echo

echo命令

echo -n:表示不换行输出

echo -e:表示输出转义符

常用转义符

选项                                                                  作用

\r                                                       光标移至行首,并且不换行

\s                                                       当前shell的名称,如bash

\t                                                        插入Tab键,制表符

\n                                                       输出换行

\f                                                        换行,但光标仍停留在原处

\                                                         表示插入""本身转义

\b                                                       表示退格 不显示前一个字符

\c                                                       抑制更多的输出或不换行

 

4.正则表达式过滤文本

1)元字符

元字符(字符匹配): . :匹配任意单个字符,可以是一个汉字

[ ] :匹配指定范围内的任意单个字符,例如[zhou]: zhou中其中一个字符,[0-9] :数字0-9之间任意一个字符

[^ ] :匹配指定范围外的任意单个字符,例如[^zhou]:除了zhou这几个字符以外的单个别的字符,[^a.z]:除了a和z之间还有一个字符不匹配外,匹配其他字符

常用的正则表达式:

 

[:alnum:] 字母和数字

[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z

[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]

[:upper:] 大写字母

[:blank:] 空白字符(空格和制表符)

[:space:] 包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广

 

 

\w #匹配单词构成部分,等价于[_[:alnum:]]

\W #匹配非单词构成部分,等价于[^_[:alnum:]]

\S     #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

\s     #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符

 

 

2)表示次数

*          #匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.*         #任意长度的任意字符,不包括0次
\?        #匹配其前面的字符出现0次或1次,即:可有可无
\+        #匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
\{n\}     #匹配前面的字符n次
\{m,n\} #匹配前面的字符至少m次,至多n次
\{,n\}    #匹配前面的字符至多n次,<=n
\{n,\}    #匹配前面的字符至少n次

 

3)位置锚定

^                     #行首锚定, 用于模式的最左侧
$                    #行尾锚定,用于模式的最右侧
^PATTERN$   #用于模式匹配整行 (单独一行 只有root)
^$                   #空行
^[[:space:]]*$  # 空白行
\< 或 \b           #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部)
\> 或 \b           #词尾锚定,用于单词模式的右侧
\<PATTERN\> #匹配整个单词

4)分组或其他

分组:

() 将多个字符捆绑在一起,当作一个整体处理,如:(root)+

后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名

方式为: \1, \2, \3, ...

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

 

或者 :  \|

 

5)扩展正则表达式

*   匹配前面字符任意次

? 0或1次

+ 1次或多次

{n} 匹配n次

{m,n} 至少m,至多n次

{,n} #匹配前面的字符至多n次,<=n,n可以为0

{n,} #匹配前面的字符至少n次,<=n,n可以为0

 

表示分组

() 分组

分组:() 将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+

后向引用:\1, \2, ...

| 或者 a|b           #a或b

C|cat                 #C或cat

(C|c)at               #Cat或cat

 

6)grep

格式:grep [选项]... 查找条件 目标文件

选项:

-i:查找时忽略大小写
 
 
-v:反向查找,输出与查找条件不相符的行
grep -Ev '^[[:space:]]*#|^$' /etc/fstab
 
-o 只显示匹配项 -f 对比两个文件的相同行
-c 匹配的行数 [root@localhost ky15]# grep
-c root passwd 2 -color=auto #对匹配到的文本着色显示
 
 
-m  # 匹配#次后停止
 
grep -m 1 root /etc/passwd #多个匹配只取第一个
 
 
-n 显示匹配的行号
-q 静默模式,不输出任何信息
 
-A # after, 后#行
grep -A3 root /etc/passwd #匹配到的行后3行业显示出来
 
-B # before, 前#行
-C # context, 前后各#行
 
 
-e 实现多个选项间的逻辑or关系,如:
grep –e ‘cat ' -e ‘dog' file grep -e root -e bash /etc/passwd #包含root或者包含bash 的行
 
 
-w 匹配整个单词
-E 使用ERE,相当于egrep
-F 不支持正则表达式,相当于fgrep
-f file 根据模式文件,处理两个文件相同内容 把第一个文件作为匹配条件
-r   递归目录,但不处理软链接
-R   递归目录,但处理软链接
 

6.AWK

awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出,GNU/Linux发布的AWK目前由自

由软件基金会(FSF)进行开发和维护,通常也称它为 GNU AWK

有多种版本:

AWK:原先来源于 AT & T 实验室的的AWK

NAWK:New awk,AT & T 实验室的AWK的升级版

 

1)awk流程

第一步:执行BEGIN{action;… }语句块中的语句
第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,
从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END{action;…}语句块 BEGIN语句块在awk开始从输入流中读取行之前被执行,
这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中 END语句块在
awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,
它也是一个可选语句块 pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,
则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块
 

2)基础用法

print动作

再打印一遍

 输出都是hello

 先输出hello 然后再输出第二行

 提取df中的第五行

 打印指定文件内容

 

3)awk常见的内置变量

FS :指定每行文本的字段分隔符,缺省为空格或制表符(tab)。与 “-F”作用相同 -v "FS=:"

OFS:输出时的分隔符

NF:当前处理的行的字段个数

NR:当前处理的行的行号(序数)

$0:当前处理的行的整行内容

$n:当前处理行的第n个字段(第n列)

$NF:显示最后一个字段

FILENAME:被处理的文件名

RS:行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n

 

4)模式

格式: awk '模式{处理动作}'

不支持使用行号,但是可以使用变量NR 间接指定行号

 

/pat1/ 匹配pat1 的行

/pat1/,/pat2/ 正则表达式1 到 正则表达式2 之间的行 如果匹配不到2的表达式 会匹配到文末

 

与:&&,并且关系

或:||,或者关系

非:!,取反

 

5)条件判断

if语句:awk的if语句也分为单分支、双分支和多分支

单分支为if(){}

双分支为if(){}else{}

多分支为if(){}else if(){}else{}

 

6)for

awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}'

5050

#相当于在awk里面直接做出100个数相加

posted on 2023-08-16 14:47  Tsumiki  阅读(21)  评论(0编辑  收藏  举报