shell脚本编程基础

1.语法的基本介绍

#!/bin/bash     ####使用前面的#!来告诉系统它后面的参数是用来执行该文件的程序;


shell脚本是以.sh 结尾的的文件;

脚本的执行分为两种:a.  sh    脚本的绝对路径     #####调用脚本,这个不需要文件含有执行权限;

                                    

                                    

                                   脚本调试:sh -x /mnt/date.sh

                                    

                               b. chmod    +x   filename    #####当我们的脚本写完,脚本需要执行权限

                                 脚本的绝对路径       ######执行脚本,这个需要脚本含有执行权限;

                               

2.注释

我们在编写shell编程时,以#开头的句子表示注释,除了上面提到的#!比较特殊,注释主要作用解释该命令及其工作原理;

3.变量

在shell编程中,所有的变量都是由字符串组成。要赋值给一个变量:a="hello world",现在打印变量a的内容:echo "A  is : "  echo $a

有时候变量名也容易和其他文字混淆:

num=2                             

打印出来  :echo "this  is  the $numnd" ;输出结果this  is the  ,不会是我们想的结果: this is the 2nd  ;因为shell回去搜索变量numnd 的值,因为是空值。我们可以使用花括号来定义:  echo "this  is the ${num}nd";



4.编写脚本的时候我们还需要在脚本里面写入基本作用还有作者的一些信息,如下图:


每次写一个脚本,还要编辑以上信息比较繁琐,我们可以配置文件/etc/vimrc 里面直接写好利用快捷键直接显示;


注意:在67行里面设置快捷键的时候需要尝试,因为有些快捷键是由其他功能的,两者最好不要冲突;

             66行命令的意思是新建的以 .sh 结尾的文件自动添加函数WESTOS;

4.脚本基本命令:

diff    ###比较文件的差异;以下是diff的基本介绍;



1c1
< 12345    ######表示第一个文件的内容;
---

> 123      #######表示第二个文件的内容;

diff的补丁作用

将文件file和文件file1的不同生成补丁名命为diff.path;


需要给文件打补丁,将旧文件有缺失的变成全新文件没有缺失;需要使用补丁软件path.x86_64


补全文件file1, -b ###不全文件同时保存原文件;


查看文件;file1.orig是生成的原文件;


cut    ###截取文件字符

-d   ####指定分隔符

-f    #####指定截取的第几列

-c   #####指定截取的每列第几个字符

例如我们要展示系统用户;



sort      用于字符排序


-n     ####纯数字排序                                                           -r    ####倒序

              

-u    #####删除重复数字                                                       -o   ####将排序结果输出到指定文件

                              

-t    ####指定分隔符                                                              -k   ####指定要排序的列



uniq     对重复字符处理,常常与sort联合使用

-u            ###显示唯一的一行


-d            ###显示重复的行


-c            ###显示出现的次数(前面数字是次数,后面数字是出现的数字)


&&   和  | |

&&  表示条件满足执行后面跟的命令

| |    表示条件不满足执行后面跟的命令

[ -e linux ]   &&   echo  yes   |  |      echo   no

####如果linux 文件存在这个条件满足则输出yes否则输出no;

test    判断命令

test 命令和 [ ] 命令等同;

test "$A"=="$B"   等同于 [ "$A"=="$B" ]

[ "$a" = "$b" ]  ###a是否于一致,不仅只是数值的相等·

[“$a” != "$b" ]    #####a是否于b不相等

 [   ! "$a" = "$b" ]     ####a于b不一致,且该条件不成立;


-qe      ###等于              -le    ###小于等于                - ne      ###不等于

-ge     ####大于等于      - lt  ###小于                         -gt        ###大于                         

[  参数   filename ]

-e            ####是否存在


-f             ####是否为文件





-L             ####是否为链接


-S            ####是否为套接字

-b            ####是否为块设备

-d            ####是否为目录

-c            ####是否为字符

-z         ####是否为空


-n             #####是否不为空


tr      改变字符的大小写

echo  agsgdyguDHDEWFUYUE >  linux      

tr   'a-z'   'A-Z'      <   linux     ####将Linux文件里面的小写字母用大写字母取代并打印出来;


注意 : 括号的方向,一旦方向错误,文件里面的内容会被丢失;


find      查询


-type        ####按照类型查找


-user         ####按照属主查找


-group          ###按照属组查找


-a          ###并且,通常表示至少两个条件都满足


-perm   ####按照权限条件查找


注意:/444    /表示或的意思;查找u位有w权限或者g位有w权限或者o位有w权限

-444    -表示且的意思;查找u位g位o位都有w权限的

-644   ###查找u位含有r权限和w权限,且g位含有r权限,且o位含有r权限;

/644  ###查找u位含有r权限或者w权限,或者g位含有r权限,或者o位含有r权限;

-size      ###按照文件大小查找


find /mnt/ -size -20M     ####查找小于20M


find /mnt/ -size  +20M     ####查找大于20M


-maxdepth     ###按照最大深度查找(默认最大深度为2层)


-mindepth     ###按照最小深度查找


改变软连接的属组只能改变软连接的指向文件的属组;

grep     过滤

grep   关键字   文件         ####过滤含有关键字的行

grep  ^root     文件          ####过滤以root开头的行

grep    root$     文件           ###过滤以root结尾的行

grep    -o     关键字      文件      ####将过滤的关键字竖列打印出来

grep    -i    关键字      文件         ####忽略大小写

grep    -E    "root\>"   文件       ####以root结尾的

grep    -E    "\<root"   文件       ####以root开头的

grep -E "\<root\>" linux    ####root开头和结尾的行

*          匹配字符出现[0-任意词]

?              字符出现0-1次

+              字符出现1-任意次

{ n }             字符出现n次

{ n , m }      字符出现至少n次,最多m次

{ 0 , m }       字符出现0-m次

{ n , 0 }        字符出现至少m次

(xy)n            字符出现n 次

sed   (sream   editor)    行编辑器            对字符的处理

sed  符合模式条件的处理   不符合条件模式的不予处理

处理完成以后把缓冲区的内容送往屏幕;接着处理下一行,直至文件的末尾

-p      显示

-d      删除

-a       添加

-c      改变

-w        写入

-i         插入

p   模式编辑

sed   -n  '/^UUID/p'  filename     ###显示UUID开头的行

sed   -n   '/UUID$/p'   filename     ###显示UUID结尾的

sed   -n  '2,6p'    filename          ###显示第2行和第6行

sed   -n  '2,6!p'    filename          ###显示除了第2行和第6行

a  模式编辑

sed   '/^UUID/a \hello sed /etc/fstab'              ###在文件fstab里面以UUID开头行后面添加hello sed

sed   '/^UUID/a \hello sed\westos /etc/fstab'    ###在hello  sed  后面添加westos

awk 报告生成器

awk处理机制:awk会逐行处理文本


awk -F : 'BEGIN{print "NAME"}{print $1}'  passwd     

##passwd文件里面以: 为分隔符,开始给第一行显示NAME且打印第一行;


awk -F :  '/bash$/{print $1}' passwd    ###显示passwd文件以bash结尾的行,并且打印第一竖列;


注意不要忘记-F 否则不识别:将一行当作一个列:


awk -F '/^root/{print $1}' passwd   ###显示passwd文件以root开头的行,并且打印第一列;


awk -F '/bash$/{print $1}END{print NR}'  passwd##显示passwd文件以bash结尾的行,并且打印第一列;统计行数;


awk -F : 'NR==3{print $1}'  passwd   ####显示第三行第一列;


awk -F :  'NR>=3&&NR<=6{print $1}'  passwd    ###显示第三行和第六行的第一列;


awk -F : 'NR>=3&&NR<=5&&/^a | nologin$/{print $1,$7}' passwd    

###显示第3行到第5行,并且以a开头或者以nologin结尾,打印第一竖列与第七竖列;


linux shell 的变量分类:三种分别为内部变量,环境变量,用户变量。

内部变量:系统提供,不用定义,不能修改;

环境变量:系统提供,不用定义,可以修改,利用export将用户变量转为环境变量;

用户变量:用户定义,可以修改;

(1)内部变量(系统变量,环境变量,参数变量,预定义变量)
内部变量是Linux所提供的一种特殊类型的变量,这类变量在程序中用来作出判断。在shell程序内这类变量的值是不能修改的。
   表示方法     描述
   $n     $1 表示第一个参数,$2 表示第二个参数 ...
   $#     命令行参数的个数
   $0     当前程序的名称
   $?     前一个命令或函数的返回码
   $*     以"参数1 参数2 ... " 形式保存所有参数
   $@     以"参数1" "参数2" ... 形式保存所有参数
   $$     本程序的(进程ID号)PID
(2) 环境变量
  Linux环境(也称为shell环境)由许多变量及这些变量的值组成,由这些变量和变量的值决定环境外观。这些变量就是环境变量。
包括两部分,一是,由系统设置的,主要包括: HOME,LOGNAME,MAIL,PATH,PS1,PWD,SHELL,TERM
二是,用户在命令行中设置的,使用export命令,但是用户注销时值将丢失
(3)用户变量(私有变量,本地变量)
  在命令行中自己设定的.

设置当前shell的变量

我们赋予当前shell一个变量a=1,可以查看当前变量值为1,我们在打开一个当前shell的子shell,查看变量a的值为空;


export a=1   ####将变量设定为当前shell以及子shell的环境变量


我们在打开一个子shell ,可以查看变量生效;


设置用户shell变量


在root用户的家目录下,我们卡伊看见有个隐藏文件.bash_profile 进行编辑添加 export a=2

###当前用户环境变量设置完成,

退出当前用户在进入改变量也生效;

设置系统变量

1.我们赋予当前shell 变量a=1,切换其他用户不生效;


2.以root用户的身份在/etc/profile文件里面添加 export a=1



需要注意的是:我们在配置文件系统变量设置完成,不能立刻生效,需要进行读取文件更新环境菜可以生效;

source /etc/profile           ####读取配置文件,更新环境

字符的转译以及变量的声明

\                    ##转译单个字符;

" "                      ##弱引用。批量转译”“中出现的字符;

' '                  ##强引用,批量转译' '  中出现的字符;

' ' 与" "         ##两者区别在于," " 不能转译\   `     !      $

${ }                ##变量声明

read      ####提示用户输入,并将输入赋值给变量

1.示例:vim read.sh    ####编写一个read.sh脚本


我们调用脚本进行查看;


如果我们不想让别人知道我们输入什么密码或者用户名,在脚本后面添加-s

alias    ###定义别名

1.暂时定义别名


测试结果:


这样的方法只是暂时的,当我们退出当前用户在进入的话,改别名会失效;


unalias    ####删除设置里面的xie别名;

2.永久进行别名设置

编辑配置文件/etc/bashrc, 配置完成需要进行读取更新,source /etc/bashrc


如不需要该别名,删除配置文件里面的命令或者注释掉,使用unalias删除设置的命令



1.for 语句

for N in {1..10}   ###将1到10赋值于N,

sleep 1   ###每隔一秒休眠一次


2.编写脚本check_host检查1-10主机是否可以ping通

3.编写脚本create_user自动建立userfiled的用户

4.编写脚本将/mnt/userfile 与/mnt/passwdfile 一一对应建立用户

5.编写脚本time.sh实现10s倒计时;

while 语句

1.编写脚本User.sh,当根分区的内存使用量超过80%时,每隔10s生成警告日志

if 语句

1.编写脚本User_create.sh,当文件个数不符合要求或者文件不存在时报错;

2.编写脚本test.sh,当输入cat时输出dog;当输入dog是输出cat;其他则报错;

case语句

case语句横向同时比较,效率优于if语句

1.编写脚本service_ctrl.sh,当输入命令时对httpd服务做不同的操作;

expect 语句

##需要安装expect服务##

expect : 自动应答脚本,具备自己运行的环境;针对某一个脚本,自动输出结果

1.编写脚本passwd.exp,自动修改root用户密码;

查看相关命令的脚本;

which passwd        ###

which  expect      

spawn   /bin/passwd     ###监控脚本

1.编写脚本ssh.exp,自动链接指定主机

2,编写脚本check_host.sh ,输出1-10网络相同的主机名

3.编写脚本编写1:10秒倒计时

脚本语句控制器

exit;   break;   continue;

练习脚本:

1.改变http服务的接口;

2.打印能登录系统且家目录不是/home的用户个数

打印设备的IP








猜你喜欢

转载自blog.csdn.net/weixin_39249306/article/details/80290772