写在前面

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波


一、Shell 基础知识1.1 什么是 SHELL

shell 是用户 与 Linux 内核之间的解释器

区分 shell 和 Bash:shell是解释器的总称,bash是一类解释器。

Bash基本特性

查看当前在使用得解释器,不会显示临时切换的解释器,查看当前系统支持得解释器类型

[root@liruilong ~]$ echo $SHELL #查看当前在使用得解释器,不会显示临时切换的解释器 /bin/bash [root@liruilong ~]$ cat /etc/shells #查看当前系统支持得解释器类型 /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin /bin/tcsh /bin/csh

临时使用其他的解释器,查看设置用户得解释器类型

[root@liruilong ~]$ sh #临时使用其他的解释器 [root@liruilong ~]$ useradd zhangsan #创建用户 [root@liruilong ~]$ cat /etc/passwd | grep zhangsan #查看用户得解释器类型 zhangsan:x:1002:1002::/home/zhangsan:/bin/bash [root@liruilong ~]$ usermod -s /bin/tcsh zhangsan #修改zhangsan得解释器 [root@liruilong ~]$ cat /etc/passwd | grep zhangsan zhangsan:x:1002:1002::/home/zhangsan:/bin/tcsh [root@liruilong ~]$ su - zhangsan #切换用户,验证用户得解释器类型 [zhangsan@liruilong ~]$ echo $SHELL /bin/tcsh [zhangsan@liruilong ~]$

linux命令与shell脚本命令大全(等知识的一些笔记)(1)

在这里插入图片描述

Bash的优点

[root@liruilong ~]$ history #查看历史记录 [root@liruilong ~]$ history -c #清空历史记录 [root@liruilong ~]$ vim /etc/profile #修改历史记录的数量 46 HISTSIZE=1000

[root@liruilong ~]$ alias #查看当前用户可以使用的别名

linux命令与shell脚本命令大全(等知识的一些笔记)(2)

在这里插入图片描述

[root@liruilong ~]$ vim /root/.bashrc #重开一个终端生效,针对root用户生效 alias ens33='cat /etc/sysconfig/network-scripts/ifcfg-ens33' [root@liruilong ~]$ vim /etc/bashrc #重开一个终端生效,针对所有用户生效 alias ens33='cat /etc/sysconfig/network-scripts/ifcfg-ens33'

标准输入与输出的重定向 ( >、>>、2>、2>>、&> )

正确输出重定向覆盖,> 等同于 1>

##正确输出重定向覆盖,> 等同于 1> [root@liruilong ~]$ ls /etc/passwd > /root/1.txt [root@liruilong ~]$ cat /root/1.txt /etc/passwd

正确输出重定向追加, 1>> 等同于 1>>

##正确输出重定向追加, 1>> 等同于 1>> [root@liruilong ~]$ ls /etc/passwd >> /root/1.txt [root@liruilong ~]$ cat /root/1.txt /etc/passwd /etc/passwd

错误输出重定向覆盖追加

##错误输出重定向覆盖 [root@liruilong ~]$ ls --helps 2> /root/2.txt [root@liruilong ~]$ cat /root/2.txt ls:无法识别的选项“--helps” Try 'ls --help' for more information. ##错误输出重定向追加 [root@liruilong ~]$ ls --helps 2>> /root/2.txt [root@liruilong ~]$ cat 2.txt ls:无法识别的选项“--helps” Try 'ls --help' for more information. ls:无法识别的选项“--helps” Try 'ls --help' for more information.

错误或正确的输出重定向覆盖追加

##错误或正确的输出重定向覆盖 [root@liruilong ~]$ ls /etc/shadow /root/fsdfs &> /root/3.txt [root@liruilong ~]$ cat /root/3.txt ls: 无法访问/root/fsdfs: 没有那个文件或目录 ##错误或正确的输出重定向追加 [root@liruilong ~]$ ls /etc/shadow /root/fsdfs &>> /root/3.txt [root@liruilong ~]$ cat /root/3.txt ls: 无法访问/root/fsdfs: 没有那个文件或目录 /etc/shadow [root@liruilong ~]$ cat /root/3.txt ls: 无法访问/root/fsdfs: 没有那个文件或目录 /etc/shadow

管道 ( | )

##管道的应用 [root@liruilong ~]$ cat /etc/passwd | less [root@liruilong ~]$ echo "123" | passwd --stdin zhangsan

Shell 执行命令的方式二、脚本设计与运行2.1 编写Shell 脚本

什么是 Shell 脚本 提前将可执行的命令语句写入一个文件 顺序执行 解释器逐行解释代码

第一个 Shell 脚本

编写一个 Hello Word脚本 新建文件 添加可执行语句 (命令) 给文件添加 x 执行权限

[root@liruilong ~]$ mkdir -p /root/shell/day01 [root@liruilong ~]$ vim /root/shell/day01/first.sh echo "Hello World"

规范脚本的构成

一个合格规范的脚本应该包含以下这些内容 #! 脚本声明 (使用哪种解释器解释代码) 注释信息 (步骤、思路、用途等),以 # 可执行的语句

[root@liruilong ~]$ vim /root/shell/day01/first.sh #!/bin/bash #A test program for Shell. echo "Hello World"

2.2 执行 Shell 脚本

方法一:需要为文件赋予可执行的权限 绝对路径执行 相对路径执行

[root@liruilong ~]$ chmod x /root/shell/day01/first.sh #赋予执行权限 [root@liruilong ~]$ /root/shell/day01/first.sh #以绝对路径的方式运行脚本 Hello World [root@liruilong ~]$ cd /root/shell/day01 [root@liruilong day01]# ./first.sh #以相对路径运行脚本,【.】只得是当前目录 Hello World

方法二:不需要文件有可执行的权限 sh 脚本文件名 source 脚本文件名 #不会启动子进程,通过pstree 查看进程树

linux命令与shell脚本命令大全(等知识的一些笔记)(3)

在这里插入图片描述

[root@liruilong ~]$ chmod -x /root/shell/day01/first.sh #取消脚本的执行权限[root@liruilong ~]$ ls -l /root/shell/day01/first.sh-rw-r--r-- 1 root root 58 7月 4 11:03 /root/shell/day01/first.sh[root@liruilong ~]$ sh /root/shell/day01/first.sh #用开启子进程的方式运行脚本Hello World

linux命令与shell脚本命令大全(等知识的一些笔记)(4)

![在这里插入图片描述](https://img-blog.csdnimg.cn/0ed77c927305454dbe40ae57e34b93

[root@liruilong ~]$ source /root/shell/day01/first.sh #运行脚本时不会开启子进程 Hello World

#!/bin/bash echo "Hello World" sleep 100 #休眠100秒 [root@liruilong ~]$ yum -y install psmisc #pstree的软件包 [root@liruilong ~]$ sh /root/hello.sh #终端A上运行脚本 [root@liruilong ~]$ pstree #终端B验证,查看进程树 ├─sshd─┬─sshd───bash───sh───sleep └─sshd───bash───pstree [root@liruilong ~]$ source /root/hello.sh #终端A上运行脚本 [root@liruilong ~]$ pstree #终端B验证,查看进程树 ├─sshd─┬─sshd───bash───sleep └─sshd───bash───pstree

三、变量3.1 自定义变量

以固定的名称,存放可以能有变化的值

定义变量

注意事项: = 两边不能有空格,不要使用关键字做变量名,如:ls、cd等; 如果变量名已经存在则覆盖之前的变量值; 变量名称有:字母/数字/下划线,不能以数字开始;

查看变量

###脚本中得变量并不需要回收,运行完成后系统会自动回收变量 [root@liruilong ~]$ x=12 #给变量x赋值为12 [root@liruilong ~]$ var1=centos #给变量var1赋值为centos [root@liruilong ~]$ _a=12 #变量名以下划线开头 [root@liruilong ~]$ a_0="hello world" #变量的值可以是字符串 [root@liruilong ~]$ echo $x #输出变量x的值 12 [root@liruilong ~]$ echo $_a #输出变量$_a的值 12 [root@liruilong ~]$ echo $a_0 #输出变量$_0的值 hello world [root@liruilong ~]$ echo ${var1}6.5 #输出变量 var1的值,为了区分,用{var1}表示 centos6.5 [root@liruilong ~]$ unset x #取消定义的变量x [root@liruilong ~]$ echo $x #再次输出结果为空

3.2系统预设变量

变量类型 环境变量(变量名通常大写,有操作系统维护); 位置变量(bash内置变量,存储脚本执行时的参数); 预定义变量(bash内置变量,可以调用但是不能赋值或修改); 自定义变量(用户自主设置)

环境变量

环境变量 存储在 /etc/profile 或 ~/.bash_profile 命令 env 可以列出所有环境变量 常见环境变量:PATH、PWD、USER、UID、HOME、SHELL

[root@liruilong ~]$ echo $PATH #默认搜索路径 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [root@liruilong ~]$ echo $UID #当前用户对应得UID号 0 [root@liruilong ~]$ echo $USER #当前系统得登录用户 root [root@liruilong ~]$ echo $HOME #当前登录用户得家目录 /root [root@liruilong ~]$ cd /etc/sysconfig/network-scripts/ [root@liruilong network-scripts]# echo $PWD #显示当前用户得所在路径 /etc/sysconfig/network-scripts [root@liruilong ~]$ [root@liruilong ~]$ echo $SHELL #显示当前用户使用得解释器 /bin/bash

位置变量

位置变量 存储脚本执行时的参数: 使用 $n 表示,n 为数字序列号 $1、$2、... 、${10}、${11}、...

[root@liruilong ~]$ vim /root/shell/day01/user.sh #!/bin/bash #test positional parameters. echo $1 echo $2 echo $3 [root@liruilong ~]$ bash /root/shell/day01/user.sh aa 99 cc aa 99 cc

[root@liruilong ~]$ vim /root/shell/day01/user02.sh #!/bin/bash #read username and pass from positional parameters. useradd "$1" #创建用户 echo "$2" | passwd --stdin "$1" #给用户设置密码 [root@liruilong ~]$ sh /root/shell/day01/user02.sh tom 123 更改用户 tom 的密码 。 passwd:所有的身份验证令牌已经成功更新。

预定义变量

预定义变量 用来保存脚本程序的执行信息 直接使用这些变量 不能直接为这些变量赋值

linux命令与shell脚本命令大全(等知识的一些笔记)(5)

在这里插入图片描述

[root@liruilong ~]$ ls /tmp/ [root@liruilong ~]$ echo $? #返回上一条命令的执行状态:0 为正确,非0 为错误 0 [root@liruilong ~]$ cat /root/sfsfsd cat: /root/sfsfsd: 没有那个文件或目录 [root@liruilong ~]$ echo $? #上一条命令执行失败,返回一个非0值 1 [root@liruilong ~]$ vim /root/shell/day01/pre.sh #!/bin/bash echo $0 #输出当前得脚本名 echo $* #输出所有得位置变量 echo $# #输出位置变量得数量 echo $$ #输出脚本的进程号,每次运行脚本进程号不同 [root@liruilong ~]$ bash /root/shell/day01/pre.sh aa bb 88 qq /root/shell/day01/pre.sh # $0执行结果 aa bb 88 qq # $*执行结果 4 # $#执行结果 3255 # $$脚本进程号 [root@liruilong ~]$

四、变量的扩展应用4.1 各种引号多种引号的区别

区别三种定界符 -- 双引号 " " 允许扩展,以 $ 引用其他变量; 单引号 ' ' 禁用扩展,即便 $ 也视为普通符号; 反引号 `` 将命令的执行输出作为变量值,$() 与反引号等效;

[root@liruilong ~]# touch a b c #创建的是三个文件 [root@liruilong ~]# touch "a b c" #双引号让其代表一个文件 [root@liruilong ~]# touch 'b c d' #单引号作用这里是与双引号相同 [root@liruilong ~]# ls -l #查看 -rw-r--r-- 1 root root 0 7月 6 09:36 a -rw-r--r-- 1 root root 0 7月 6 09:36 b -rw-r--r-- 1 root root 0 7月 6 09:36 c -rw-r--r-- 1 root root 0 7月 6 09:48 a b c -rw-r--r-- 1 root root 0 7月 6 09:48 b c d [root@liruilong ~]# rm -rf "a b c" #删除时要引号引起来 [root@liruilong ~]# rm -rf 'b c d'

[root@liruilong ~]# echo $HOME #输出家目录路径 /root [root@liruilong ~]# echo '$HOME' #只输出 $HOME 字符串,''屏蔽特殊符号的含义 $HOME [root@liruilong ~]# echo '$USER id is $UID' $USER id is $UID [root@liruilong ~]# echo $USER id is $UID root id is 0 [root@liruilong ~]# test=`grep root /etc/shadow` [root@liruilong ~]# test01=$(grep root /etc/shadow) [root@liruilong ~]# echo $test root:$6$Uebh9/WEzEaQfT$8b0B6oBgWUTEmYojDW9.6PHOw0.jD7A.SENsHFD/YPwh/L9jRJK0yWAtRF4BEteYZETeMiInp72dTviSKmLZf.:18501:0:99999:7::: dockerroot:!!:18691:::::: [root@liruilong ~]# echo $test01 root:$6$Uebh9/WEzEaQfT$8b0B6oBgWUTEmYojDW9.6PHOw0.jD7A.SENsHFD/YPwh/L9jRJK0yWAtRF4BEteYZETeMiInp72dTviSKmLZf.:18501:0:99999:7::: dockerroot:!!:18691:::::: [root@liruilong ~]#

4.2 read 命令定义变量read 标准输入取值

read 标准输入取值 read 从键盘读入变量值完成赋值 格式:read [-p "提示信息"] 变量名 -p 可选,-t 可指定超时秒数,-s 设置是否在终端显示输入的内容

交互式定义变量

[root@liruilong ~]# read name #交互式定义变量 haha #输入名字 [root@liruilong ~]# echo $name #查看变量 haha

[root@liruilong ~]# read -p "请输入用户名:" name #交互式定义变量 请输入用户名:xixi [root@liruilong ~]# echo $name #查看变量 xixi

从键盘读取用户名密码,创建用户并设置密码

[root@liruilong ~]# vim /root/shell/day01/user03.sh #!/bin/bash ##read 从键盘读取用户名密码,创建用户并设置密码 read -p "请输入一个用户名:" name read -p "请输入密码:" pass useradd $name echo "$pass" | passwd --stdin $name ##脚本测试 [root@liruilong ~]# source /root/shell/day01/user03.sh 请输入一个用户名:nana 请输入密码:123456 更改用户 nana 的密码 。 passwd:所有的身份验证令牌已经成功更新。

read 从键盘读取用户名密码,创建用户并设置密码,要求不显示输入密码

[root@liruilong ~]# vim /root/shell/day01/user03.sh #!/bin/bash ##read 从键盘读取用户名密码,创建用户并设置密码,要求不显示输入密码 read -p "请输入一个用户名:" name read -p "请输入密码:" -s pass useradd $name echo "$pass" | passwd --stdin $name ##脚本测试 [root@liruilong ~]# source /root/shell/day01/user03.sh 请输入一个用户名:haha 请输入密码:更改用户 haha 的密码 。 passwd:所有的身份验证令牌已经成功更新。 [root@liruilong ~]# vim /root/shell/day01/user03.sh #!/bin/bash

不输入就会自动退出:如果后面不加秒数,则不会自动退出

##read 从键盘读取用户名密码,创建用户并设置密码,要求不显示输入密码 ##-t 多少秒不输入就会自动退出:如果后面不加秒数,则不会自动退出 read -p "请输入一个用户名:" name read -p "请输入密码:" -s -t 3 pass useradd $name echo "$pass" | passwd --stdin $name ##脚本测试 [root@liruilong ~]# source /root/shell/day01/user03.sh 请输入一个用户名:lisi 请输入密码:更改用户 lisi 的密码 。 #超过3秒退出 passwd: 鉴定令牌操作错误

4.3 全局变量 or 局部变量变量的作用范围

变量的作用范围 -- 局部变量 新定义的变量默认只是在当前 Shell 环境中有效,无法在子 Shell 环境中使用 全局变量 系统中的任何 Shell 环境中都有效

####开启两个终端,A和B来测试 #终端A上操作 [root@liruilong ~]# x=11 #定义局部变量 [root@liruilong ~]# sh #进入sh子进程 sh-4.2# echo $x #无此变量,输出为空 #终端B上操作 [root@liruilong ~]# pstree #查看进程树 ...... ├─sshd─┬─sshd───bash───sh │ └─sshd───bash───pstree ......

使用 export 定义全局变量

#终端A上操作 [root@liruilong ~]# export x=12 #定义全局变量 [root@liruilong ~]# sh #开启sh子进程 sh-4.2# echo $x #新的解释器里变量也生效 12 sh-4.2# bash #开启bash子进程 [root@liruilong ~]# echo $x #新的解释器里变量也生效 12 [root@liruilong ~]# pstree #查看进程树 ...... ├─sshd─┬─sshd───bash───sh───bash └─sshd───bash───pstree ......

五、Shell 中的运算5.1 整数运算基本运算法则

基本运算法则 四则运算 加法:num1 num2 减法:num1 - num2 乘法:num1 * num2 整除:num1 / num2 取余数运算 求模:num1 % num2

$[] 算式替换

[root@liruilong ~]# echo $[1 2] 3 [root@liruilong ~]# echo $[2*3] 6

[root@liruilong ~]# x=15;y=3 #定义两个临时变量x,y [root@liruilong ~]# echo $[x y] #加法运算 18 [root@liruilong ~]# echo $[x-y] #减法运算 12 [root@liruilong ~]# echo $[x*y] #乘法运算 45 [root@liruilong ~]# echo $[x/3] #除法运算 5 [root@liruilong ~]# echo $[x%3] #取余运算(除尽) 0 [root@liruilong ~]# echo $[x%2] #取余运算(未除尽) 1 [root@liruilong ~]# x=15;y=3 #定义两个临时变量x,y [root@liruilong ~]# echo $((x y)) #加法运算 18 [root@liruilong ~]# echo $((x-y)) #减法运算 12 [root@liruilong ~]# echo $((x*y)) #乘法运算 45 [root@liruilong ~]# echo $((x/y)) #除法运算 5 [root@liruilong ~]# echo $((x%y)) #取余运算(除尽) 0 [root@liruilong ~]# echo $((x%y)) #取余运算(未除尽) 1 [root@liruilong ~]# x=2 #定义变量x=2 [root@liruilong ~]# echo $[x =4] #输出x值,x=x 4 6 [root@liruilong ~]# echo $x #输出x值 6

变量的自增/减等操作

[root@liruilong ~]# echo $[x =1] #输出x值,x=x 1 7 [root@liruilong ~]# echo $x #输出x值 7 [root@liruilong ~]# echo $[x*=3] #输出x值,x=x*3 21 [root@liruilong ~]# echo $x #输出x值 21 [root@liruilong ~]# echo $[x ] #输出x 1前的值 21 [root@liruilong ~]# echo $x #这是x 1后的值 22 [root@liruilong ~]# echo $[x--] #输出x-1前的值 22 [root@liruilong ~]# echo $x #输出x-1后的值 21

let 指定算术运算

####let 用于指定算术运算 [root@liruilong ~]# let i=2*3 #将算术运算 2*3 赋予变量 i [root@liruilong ~]# echo $i 6 [root@liruilong ~]# let i=3*6 #将算术运算 3*6 赋予变量 i [root@liruilong ~]# echo $i 18 [root@liruilong ~]# b=2 #定义变量 [root@liruilong ~]# let b =2 #变量赋值,b=b 2 [root@liruilong ~]# echo $b 4 [root@liruilong ~]# let b*=3 #变量赋值,b=b*3 [root@liruilong ~]# echo $b 12 [root@liruilong ~]# x=2 [root@liruilong ~]# let x ;echo $x # ;用来区分两条命令 3 [root@liruilong ~]# let x ;echo $x # ;用来区分两条命令 4 [root@liruilong ~]# let x =3;echo $x # ;用来区分两条命令 7

5.2 小数运算bc计算器

Bash 内建机制仅支持整数运算,不支持小数运算

[root@liruilong ~]# echo $[12.2 23] -bash: 12.2 23: 语法错误: 无效的算术运算符 (错误符号是 ".2 23")

我们可以通过计算器软件 bc 实现小数运算

我们没有该软件则需要使用yum安装; bc支持交换式和非交换式两种计算,scale=n 可以约束小数位,quit 退出交互式计算

[root@liruilong ~]# yum -y install bc #安装bc软件包 ###使用bc进行交互运算 [root@liruilong ~]# bc 12 23 #加法运算 35 23.43*1.243 #乘法运算 29.123 23/2 #除法运算 11 23%3 #取余运算 2 quit #退出命令 [root@liruilong ~]# echo "1.2 3.3" | bc 4.5 [root@liruilong ~]# echo "1.2 3.3;3.8*2.7" | bc #同时进行多个运算 4.5 10.2 [root@liruilong ~]# echo "scale=2;10/2" |bc #scale=2 结果小数位保留两位 5.00 [root@liruilong ~]# echo "scale=2;17/2" |bc 8.50 [root@liruilong ~]# echo "scale=2;17.34/2" |bc #scale=2 结果小数位保留两位

小数的比较

[root@liruilong ~]# echo "1>2" | bc #比较错误,1小于2,结果为0 0 [root@liruilong ~]# echo "5>2" | bc #比较正确,5大于2,结果为1 1 [root@liruilong ~]# echo "2==2" | bc #比较正确,2等于2,结果为1 1 [root@liruilong ~]# echo "2!=2" | bc #比较错误,2等于2,结果为0 0 [root@liruilong ~]# echo "12.34 < 8.8" | bc #比较错误,12.34 大于 8.8,结果为0 0 [root@liruilong ~]# echo "12.34 != 8.8" | bc #比较正确,12.34不等于8.8 [root@liruilong ~]# echo "hello world" #echo 默认会换行 hello world [root@liruilong ~]# echo -n "hello world" #-n 取消 echo 命令的默认换行 hello world [root@liruilong ~]#

六、综合案例6.1 监控脚本之显示硬件信息echo回显改变echo输出的文本颜色

30:黑 34:蓝色 31:红 35:紫色 32:绿 36:深绿 33:黄 37:白色

[root@liruilong ~]# echo -e "\033[32m天气预报\033[0m" #0m还原文字颜色,让颜色只作用 于当前字体 hello #32绿色字

监控硬件信息

显示服务器硬件信息

###最小化安装需要安装查看IP的软件包 [root@liruilong ~]# which ifconfig /usr/sbin/ifconfig [root@liruilong ~]# rpm -qf /usr/sbin/ifconfig net-tools-2.0-0.22.20131004git.el7.x86_64 [root@liruilong ~]# vim /root/shell/day01/info.sh #!/bin/bash ##显示服务器硬件信息 echo -e "\033[34m----------服务器硬件信息----------\033[0m" echo -e "\033[32m网卡信息如下:\033[0m" ifconfig ens33 | grep "inet" echo -e "\033[32m剩余内容容量信息如下: \033[0m" grep MemAvailable /proc/meminfo echo -e "\033[32m磁盘容量信息如下: \033[0m" df -h / echo -e "\033[32mCPU信息如下:\033[0m" grep "model name" /proc/cpuinfo [root@liruilong ~]# sh /root/shell/day01/info.sh #运行脚本 ----------服务器硬件信息---------- 网卡信息如下: inet 192.168.4.5 netmask 255.255.255.0 broadcast 192.168.4.255 inet6 fe80::452e:bf37:6ef7:c2fa prefixlen 64 scopeid 0x20<link> 剩余内容容量信息如下: MemAvailable: 1238268 kB 磁盘容量信息如下: 文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/centos-root 50G 7.2G 43G 15% / CPU信息如下: model name : Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz

linux命令与shell脚本命令大全(等知识的一些笔记)(6)

在这里插入图片描述

计算例题

[root@liruilong ~]# vim /root/shell/day01/calc.sh #!/bin/bash ##计算1 2 3,..., n的和,可以使用n*(n 1)/2公式快速计算结果 read -p "请输入一个正整数:" num sum=$[num*(num 1)/2] echo -e "\033[32m$num以内整数的总和是:$sum \033[0m" [root@liruilong ~]# sh /root/shell/day01/calc.sh 请输入一个正整数:23 23以内整数的总和是:276 [root@liruilong ~]# vim /root/shell/day01/area.sh #!/bin/bash ##使用三角形的底边和高计算面积:A=1/2底高 read -p "请输入三角形底边长度:" bottom read -p "请输入三角形的高度:" hight A=$(echo "scale=2;1/2*$bottom*$hight" | bc) echo -e "\033[32m三角形的面积是:$A\033[0m" [root@liruilong ~]# sh /root/shell/day01/area.sh 请输入三角形底边长度:23 请输入三角形的高度:5 三角形的面积是:57.50 [root@liruilong ~]# vim /root/shell/day01/tixingmianhi.sh #!/bin/bash ##梯形面积:(上底边长度 下底边长度)*高/2 read -p "请输入梯形上底边长度:" a read -p "请输入梯形下底边长度:" b read -p "请输入梯形高度:" h A=$(echo "scale=2;($a $b)*$h/2" | bc) echo -e "\033[32m梯形面积是:$A\033[0m" [root@liruilong ~]# sh -x /root/shell/day01/tixingmianhi.sh #-x执行时测试 read -p 请输入梯形上底边长度: a 请输入梯形上底边长度:32 read -p 请输入梯形下底边长度: b 请输入梯形下底边长度:45 read -p 请输入梯形高度: h 请输入梯形高度:7 echo 'scale=2;(32 45)*7/2' bc A=269.50 echo -e '\033[32m梯形面积是:269.50\033[0m' 梯形面积是:269.50 [root@liruilong ~]# vim /root/shell/day01/yuanmianji.sh #!/bin/bash ###使用A=πr2 公式计算圆的面积,取2位小数点精度,π=3.14 read -p "请输入圆的半径:" r A=`echo "scale=2;3.14*$r*2" | bc` echo -e "\033[32m圆的面积是:$A\033[0m" [root@liruilong ~]# sh -x /root/shell/day01/yuanmianji.sh #-x执行时测试 read -p 请输入圆的半径: r 请输入圆的半径:25 echo 'scale=2;3.14*25*2' bc A=157.00 echo -e '\033[32m圆的面积是:157.00\033[0m' 圆的面积是:157.00

配置 YUM 源脚本

[root@liruilong ~]# vim /root/shell/day01/yum.sh #!/bin/bash ###配置本地yum仓库 #删除所有.repo文件 rm -rf /etc/yum.repos.d/* #挂载本地光盘 mkdir /centos mount /dev/cdrom /centos chmod x /etc/rc.d/rc.local echo "mount /dev/cdrom /centos" >> /etc/rc.d/rc.local #创建yum源配置文件 echo "[Centos] name=centos7.5 baseurl=file:///centos enabled=1 gpgcheck=0" > /etc/yum.repos.d/centos.repo #yum 测试 yum clean all yum repolist

[root@liruilong ~]# sh -x /root/shell/day01/yum.sh rm -rf /etc/yum.repos.d/centos.repo mkdir /centos mount /dev/cdrom /centos mount: /dev/sr0 写保护,将以只读方式挂载 chmod x /etc/rc.d/rc.local echo 'mount /dev/cdrom /centos' echo '[Centos] name=centos7.5 baseurl=file:///centos enabled=1 gpgcheck=0' yum clean all yum repolist

七、字符串处理与变量初始化字符串处理机制子串截取

┌──(liruilong㉿Liruilong)-[/mnt/c/Users/lenovo] └─$ name=liruilong ┌──(liruilong㉿Liruilong)-[/mnt/c/Users/lenovo] └─$ echo $name liruilong ┌──(liruilong㉿Liruilong)-[/mnt/c/Users/lenovo] └─$ echo ${#name} 9 ┌──(liruilong㉿Liruilong)-[/mnt/c/Users/lenovo] └─$ echo ${name:0:3} lir ┌──(liruilong㉿Liruilong)-[/mnt/c/Users/lenovo] └─$ echo ${name:3:3} uil ┌──(liruilong㉿Liruilong)-[/mnt/c/Users/lenovo] └─$ echo ${name:3:-3} uil

子串替换

子串替换时,变量本身的值并不会变化,只会把变化的值输出到屏幕

###子串替换时,变量本身的值并不会变化,只会把变化的值输出到屏幕 [root@liruilong ~]# phone=13812345678 [root@liruilong ~]# echo ${phone/3/X} # / 替换变量中的第一个3 1X812345678 [root@liruilong ~]# echo ${phone//3/X} # // 替换变量中所有3 1X812X45678 [root@liruilong ~]# info=$(head -1 /etc/passwd) #定义变量 [root@liruilong ~]# echo $info #查看变量的值 root:x:0:0:root:/root:/bin/bash [root@liruilong ~]# echo ${info/root/ROOT} #替换单个root为大写 ROOT:x:0:0:root:/root:/bin/bash [root@liruilong ~]# echo ${info//root/ROOT} #替换所有root为大写 ROOT:x:0:0:ROOT:/ROOT:/bin/bash

字串掐头

[root@liruilong ~]# A=$(head -1 /etc/passwd) #定义变量 [root@liruilong ~]# echo $A #查看变量的值 root:x:0:0:root:/root:/bin/bash [root@liruilong ~]# echo ${A#*:} #删除字串A中,第一个 : 前的所有字符 x:0:0:root:/root:/bin/bash [root@liruilong ~]# echo ${A##*:} #删除字串A中,最后一个 : 前的所有字符 /bin/bash [root@liruilong ~]# echo $A #变量A的值不会发生变化 root:x:0:0:root:/root:/bin/bash

字串去尾

[root@liruilong ~]# A=$(head -1 /etc/passwd) #定义变量 [root@liruilong ~]# echo $A #查看变量的值 root:x:0:0:root:/root:/bin/bash [root@liruilong ~]# echo ${A%:*} #删除字串A中,最后一个 : 后的所有字符 root:x:0:0:root:/root [root@liruilong ~]# echo ${A%%:*} #删除字串A中,第一个 : 后的所有字符 root [root@liruilong ~]# echo $A #变量A的值不会发生变化 root:x:0:0:root:/root:/bin/bash

批量修改文件扩展名

[root@liruilong ~]# cd /root/shell/day03/ [root@liruilong day03]# touch {a,b,c,d,e,f}.txt [root@liruilong day03]# vim /root/shell/day03/rename1.sh #!/bin/bash ####批量修改目录下的以.txt结尾的文件为.doc结尾 for i in $(ls *.txt) do mv $i ${i%.*}.doc #通过字符串去尾的去做 done ###脚本验证 [root@liruilong day03]# sh ./rename1.sh [root@liruilong day03]# ls [root@liruilong day03]# vim /root/shell/day03/rename2.sh #!/bin/bash ###批量修改文件扩展名,$1为原扩展名,$2为新扩展名 for i in $(ls *.$1) do mv $i ${i%.*}.$2 done ###脚本验证 [root@liruilong day03]# sh ./rename1.sh doc pdf [root@liruilong day03]# ls

变量初始化::

变量初始化 变量有值,则返回该变量的值 变量无值,则返回初始值 格式:${变量:-关键字}

[root@liruilong ~]# X=123 [root@liruilong ~]# echo ${X:-xyz} #变量有值,输出该变量的值 123 [root@liruilong ~]# echo ${ABC:-xyz} #变量无值,输出该变量的初始值 xyz

创建系统用户

[root@liruilong ~]# vim /root/shell/day03/user03.sh #!/bin/bash ##创建系统用户,未设置密码,会自动赋予用户初始密码12345 ###定义函数,输出文字的颜色 color(){ echo -e "\033[32m$1\033[0m" } read -p "请输入用户名:" iname if [ -z "$iname" ];then color "未输入用户名,脚本将退出..." exit fi ###输入密码,不输入密码,则赋予初始密码123456 read -p "请输入密码:" ipass ipass=${ipass:-123456} useradd "$iname" echo "$ipass" | passwd --stdin "$iname" ###测试脚本 [root@liruilong ~]# sh /root/shell/day03/user3.sh 请输入用户名: 未输入用户名,脚本将退出... [root@liruilong ~]# sh /root/shell/day03/user3.sh 请输入用户名:zhang 请输入密码: 更改用户 zhang 的密码 。 passwd:所有的身份验证令牌已经成功更新。

一、使用sed修改配置1.1 常用sed指令

常用sed指令 p(print): 打印行 d(delete): 删除行 c(replace): 替换行 s(substitution): 替换关键词 =:打印行号

1.2 过滤数据

Print 指令

##过滤网卡IP地址 [root@liruilong ~]# sed -n '/IPADDR/p' /etc/sysconfig/network-scripts/ifcfg-ens33 IPADDR=192.168.4.5 ##过滤内存信息 [root@liruilong ~]# free | sed -n '/Mem/p' Mem: 1865280 373344 1072176 10544 419760 1278920 ##过滤磁盘根分区信息(根分区是以/ 结尾的分区) [root@liruilong ~]# df -h | sed -n '/\/$/p' /dev/mapper/centos-root 50G 3.4G 47G 7% / ##显示第1、3、6行内容 [root@liruilong ~]# sed -n '1p;3p;6p' /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:2:2:daemon:/sbin:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync ##打印第2行以外的所有其他行内容 [root@liruilong ~]# sed -n '2!p' /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4

1.3 删除数据

Delete 指令 (不使用-i 选项,源文件不会被修改)

##删除/etc/hosts全文,没有定位条件等于匹配所有行 [root@liruilong ~]# sed ‘d’ /etc/hosts ##删除/tmp/fstab 的1到3行 [root@liruilong ~]# cat /etc/fstab > /tmp/fstab [root@liruilong ~]# sed "1,3d" /tmp/fstab [root@liruilong ~]# vim /tmp/fstab ##删除不包含dev的行 [root@liruilong ~]# sed '/dev/!d' /tmp/fstab ##删除所有以 # 符号开头的行 [root@liruilong ~]# sed '/^#/d' /tmp/fstab ##删除空白行 [root@liruilong ~]# sed '/^$/d' /tmp/fstab

1.4 替换行

Replace 指令(不使用 -i 选项,源文件不会被修改)

##所有行替换为 123456 [root@liruilong ~]# sed 'c 123456' /tmp/fstab 123456 123456 123456 123456 123456 123456 123456 123456 123456 123456 123456 123456 ##替换IP地址为 1.1.1.1 [root@liruilong ~]# file=/etc/sysconfig/network-scripts/ifcfg-ens33 [root@liruilong ~]# sed '/IPADDR/c IPADDR=1.1.1.1' $file TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=ens33 UUID=314ef20c-394e-4ef6-ba3b-0c6aaf47d1fc DEVICE=ens33 ONBOOT=yes IPADDR=1.1.1.1 PREFIX=24 ##替换/etc/hosts中包含127的行为 127.0.0.1 [root@liruilong ~]# cat /etc/hosts [root@liruilong ~]# sed '/127/c 127.0.0.1' /etc/hosts 127.0.0.1 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 ##替换文件的第四行为 xxxx [root@liruilong ~]# sed '4c xxxx' /etc/shells /bin/sh /bin/bash /sbin/nologin xxxx /usr/bin/bash /usr/sbin/nologin /bin/tcsh /bin/csh

1.5 替换关键词

Substitution指令(不使用 -i 选项,源文件不会被修改)

##通过echo命令定义测试文件 [root@liruilong ~]# echo "2046 2048 2046 2046 > 1001 2046 2999 1888 > 2046 2046 2046 2046" > test.txt

##查看测试文件的内容 [root@liruilong ~]# cat test.txt 2046 2048 2046 2046 1001 2046 2999 1888 2046 2046 2046 2046 ##把每一行的第一个2046替换为xxxx [root@liruilong ~]# sed 's/2046/xxxx/' test.txt xxxx 2048 2046 2046 1001 xxxx 2999 1888 xxxx 2046 2046 2046 ##把每行中的所有的2046替换为xxxx [root@liruilong ~]# sed 's/2046/xxxx/g' test.txt xxxx 2048 xxxx xxxx 1001 xxxx 2999 1888 xxxx xxxx xxxx xxxx ##把每行中的第2个2046替换为xxxx [root@liruilong ~]# sed 's/2046/xxxx/2' test.txt 2046 2048 xxxx 2046 1001 2046 2999 1888 2046 xxxx 2046 2046 ##把每行中的所有2046替换为(2046); &就代表被替换的参数 [root@liruilong ~]# sed 's/2046/(&)/g' test.txt (2046) 2048 (2046) (2046) 1001 (2046) 2999 1888 (2046) (2046) (2046) (2046) ##把每行中的所有2046替换为2046-1111;&就代表被替换的参数 [root@liruilong ~]# sed 's/2046/&-1111/' test.txt 2046-1111 2048 2046 2046 1001 2046-1111 2999 1888 2046-1111 2046 2046 2046 ##把第2行中的所有2046替换为xxxx [root@liruilong ~]# sed '2s/2046/xxxx/g' test.txt 2046 2048 2046 2046 1001 xxxx 2999 1888 2046 2046 2046 2046 ##把第2行中的所有2046替换为空,等同于删除操作 [root@liruilong ~]# sed '2s/2046//g' test.txt 2046 2048 2046 2046 1001 2999 1888 2046 2046 2046 2046 ##只输出修改过的行 [root@liruilong ~]# sed -n '2s/2046/xxxx/p' test.txt 1001 xxxx 2999 1888

正则符号() 具有保留的功能

[root@liruilong ~]# echo "hello the world" | sed -r 's/^(.)(.*)(.)$/\3\2\1/' dello the worlh [root@liruilong ~]# echo "hello the world" | sed -r 's/^(.)(.*)(.)$/\3\1\2/' dhello the worl [root@liruilong ~]# echo "hello the world" | sed -r 's/^(.)(.*)(.)$/\3\3/' dd [root@liruilong ~]# echo "hello the world" | sed -r 's/^(.)(.*)(.)$/\3\3\2\1\1/' ddello the worlhh

1.8 打印行号

##打印第2行的行号 [root@liruilong ~]# sed -n '2=' /etc/passwd 2 ##打印包含root的行号 [root@liruilong ~]# sed -n '/root/=' /etc/passwd 1 10 ##打印bash结尾的行的行号 [root@liruilong ~]# sed -n '/bash$/=' /etc/passwd 1 42 ##$代表最后一行,打印最后一行的行号 [root@liruilong ~]# sed -n '$=' /etc/passwd 42

二、sed 多行文本处理2.1 文本块指令

i (insert): 插入 a (append): 追加 r (read): 读 取文件 | 导入文件内容 w (write): 文件另存为 | 导出文件内容

插入指令 Insert (插入,行前写入)

##查看test.txt文件内容 [root@liruilong ~]# cat test.txt 2046 2048 2046 2046 1001 2046 2999 1888 2046 2046 2046 2046 ##在第2行前插入 ABC_XYZ [root@liruilong ~]# sed '2i ABC_XYZ' test.txt 2046 2048 2046 2046 ABC_XYZ 1001 2046 2999 1888 2046 2046 2046 2046 ##在第3 行前插入 ABC_XYZ [root@liruilong ~]# sed '3i ABC_XYZ' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 ABC_XYZ 2046 2046 2046 2046 ##在包含 2046的行前插入两行数据ABC\nXYZ,\n是换行符 [root@liruilong ~]# sed '/2046/i ABC\nXYZ' test.txt ABC XYZ 2046 2048 2046 2046 ABC XYZ 1001 2046 2999 1888 ABC XYZ 2046 2046 2046 2046 ##在包含 1888 的行前插入两行数据ABC\nXYZ,\n是换行符 [root@liruilong ~]# sed '/1888/i ABC\nXYZ' test.txt 2046 2048 2046 2046 ABC XYZ 1001 2046 2999 1888 2046 2046 2046 2046

Append(追加,行后写入)

##在第2行后面插入 ABC_XYZ [root@liruilong ~]# sed '2a ABC_XYZ' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 ABC_XYZ 2046 2046 2046 2046 ##在第3行后面插入 ABC_XYZ [root@liruilong ~]# sed '3a ABC_XYZ' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 2046 2046 2046 2046 ABC_XYZ ##在包含 2046的行后面插入两行数据ABC\nXYZ,\n是换行符 [root@liruilong ~]# sed '/2046/a ABC\nXYZ' test.txt 2046 2048 2046 2046 ABC XYZ 1001 2046 2999 1888 ABC XYZ 2046 2046 2046 2046 ABC XYZ ##在包含 1888 的行后面插入两行数据ABC\nXYZ,\n是换行符 [root@liruilong ~]# sed '/1888/a ABC\nXYZ' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 ABC XYZ 2046 2046 2046 2046

导入指令:Read (将其他文件的内容导入)

##将/etc/hosts中的内容读入到 test.txt 文件第2行的后面 [root@liruilong ~]# sed '2r /etc/hosts' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 2046 2046 2046 2046 ##将/etc/hosts中的内容读入到 test.txt 文件每一行数据的后面 [root@liruilong ~]# sed 'r /etc/hosts' test.txt 2046 2048 2046 2046 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 1001 2046 2999 1888 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 2046 2046 2046 2046 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 ##将/etc/hosts中的内容读入到 test.txt 文件中包含 1888字串所在行的后面 [root@liruilong ~]# sed '/1888/r /etc/hosts' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 2046 2046 2046 2046

导出指令:Write (将文件内容导出另存到其他文件)

##将test.txt 文件的所有内容另存为一个新文件 copy_test.txt [root@liruilong ~]# sed 'w copy_test.txt' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 2046 2046 2046 2046 [root@liruilong ~]# cat copy_test.txt #查看文件的内容 2046 2048 2046 2046 1001 2046 2999 1888 2046 2046 2046 2046 ##将test.txt 文件的 2到3行另存为新文件line.txt [root@liruilong ~]# sed '2,3w line.txt' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 2046 2046 2046 2046 [root@liruilong ~]# cat line.txt #查看新文件的内容 1001 2046 2999 1888 2046 2046 2046 2046 ##将test.txt 文件中所有包含1888的行另存为新文件 1888.txt [root@liruilong ~]# sed '/1888/w /opt/1888.txt' test.txt 2046 2048 2046 2046 1001 2046 2999 1888 2046 2046 2046 2046 [root@liruilong ~]# cat /opt/1888.txt #查看文件的内容 1001 2046 2999 1888

三、sed综合案例

点名器

一、awk基础语法

awk 编程语言/数据处理引擎 创造者:Aho、Weinberger、Kernighan 基于模式匹配检查输入文本,逐行处理并输出 通常用于在 Shell 脚本中,获取指定的数据 单独用时,可对文本数据做统计

awk 流程控制

格式1:前置命令| awk [选项] , [条件] (指令)' 格式2: awk [选项] ' [条件] {指令}, 文件.... 格式3: awk ,BEGIN{} [条件]{} END{}' 文件....

if语句单分支if判断

awk '{指令}' 文件

###if是指令必须放到{ if(){} }中 #如果UID大于等于1000时,i自加1;最后输出i的值,i作为变量默认值为0 [root@liruilong ~]# awk -F: '{if($3>=1000){i }} END{print i}' /etc/passwd 2 ###当$1 用户名为root时,打印用户名和UID [root@liruilong ~]# awk -F: '{if($1=="root"){print $1,$3}}' /etc/passwd root 0 ###查看CPU的负载情况 [root@liruilong ~]# uptime 10:53:35 up 2 min, 1 user, load average: 0.33, 0.33, 0.14 ###当cpu 15分钟的负载大于0.01时,打印15分钟的负载信息 [root@liruilong ~]# uptime | awk '{if($NF>0.01){print "CPUload:",$NF}}' CPUload: 0.13

双分支if判断

awk '{指令}' 文件

####统计普通用户和系统用户的个数 ##普通用户的UID号大于等于1000;系统用户的UID小于1000 [root@liruilong ~]# awk -F: '{if($3>=1000){i } else{j }} END{print "普通用户:"i,"系统用户:"j}' /etc/passwd 普通用户:3 系统用户:34 [root@liruilong ~]# #### 统计普通文件和目录的个数 ## 普通文件的属性以“-”开头,非“-”开头的也是目录也可以是快捷方式 [root@liruilong ~]# ls -l /etc/ | awk '{ if($1~/^-/){x } else{y } } END{print "普通文件个数:"x,"目录个数:"y}' 普通文件个数:122 目录个数:148

多分支if判断

awk '{指令}' 文件

###awk '{ if(){} else if(){} else{} } END{}' [root@liruilong ~]# ls -l /etc/ | awk '{ if($1~/^-/){x } else if($1~/^d/){y } else{z } } END{print "普通文件:"x,"\n目录个数:",y,"\n其他:",z}' 普通文件:118 目录个数: 106 其他: 17 [root@liruilong ~]#

for循环

awk 的for 循环采用与C语言一样的语法格式: for(表达式1;表达式2;表达式3) {指令}

##i=1,每循环一次i的值加1 [root@liruilong ~]# awk 'BEGIN{ for(i=1;i<=5;i ) {print i} }' 1 2 3 4 5 ##i=5,每循环一次i的值减1 [root@liruilong ~]# awk 'BEGIN{ for(i=5;i>=1;i--){print i} }' 5 4 3 2

awk 数组与应用案例awk 数组的定义及使用

数组的下标可以是数字,也可以是字符串

###给数组name添加两个值,并打印数值 [root@liruilong ~]# awk 'BEGIN{ > name[0]="jim";name[1]="tom";print name[1],name[0] > }' tom jim ###给数组name添加两个值,调用数组中的值 [root@liruilong ~]# awk 'BEGIN{ > name[0]="jim";name[1]="tom";print name[1],name[1],name[0] > }' tom tom jim

定义数组age,age[tom]的值为22,age[jim]的值为18

[root@liruilong ~]# awk 'BEGIN{ > age["tom"]=22;age["jim"]=18;print age["tom"],age["jim"] > }' 22 18

遍历数组的值

###定义数组x,赋值,用for循环取数组中的值 [root@liruilong ~]# awk 'BEGIN{ x[0]=0;x[1]=11;x[2]=12;x[3]=13;x[4]=14; > for(i in x){print i,x[i]} > }' 4 14 0 0 1 11 2 12 3 13

应用案例

分组统计

###IP为数组,数组的下表为access_log 第一列的ip地址; 数组对应的值为 ip地址出现的次数 [root@liruilong ~]# awk '{IP[$1] } END{ for(i in IP){print i,IP[i]} }' /root/access_log 172.40.1.14 1 172.40.1.1 1 172.40.1.16 4 172.40.1.17 6 172.40.1.18 3

统计每个系统账户登录的次数

[root@liruilong ~]# who | awk '{wh[$1] } END{for(i in wh){print i,wh[i]} }' root 2 [root@liruilong ~]#

awk 综合案例ss命令

[root@liruilong ~]# ss -at State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 127.0.0.1:webcache *:* LISTEN 0 128 *:ssh *:* LISTEN 0 128 [root@liruilong ~]# ss -atu #查看tcp和udp协议 #查看tcp和udp协议,以数字显示,端口都变成了数字模式 [root@liruilong ~]# ss -atun #查看tcp和udp协议,以数字显示,端口都变成了数字模式,显示进程名和PID号 [root@liruilong ~]# ss -atunp #查看tcp和udp协议,以数字显示,端口都变成了数字模式,显示进程名和PID号,不显示标题行 [root@liruilong ~]# ss -atunpH [root@liruilong ~]# ss -s ##汇总所有的结果

过滤连接状态

[root@liruilong ~]# vim /root/shell/day05/net.sh #!/bin/bash ##所有TCP连接的个数 TCP_Total=$(ss -s | awk '$1=="TCP"{print $2}') ##所有UDP连接的个数 UDP_Total=$(ss -s | awk '$1=="UDP"{print $2}') ##所有处于 Listen 监听状态的 TCP 端口个数 TCP_Listen_Total=$(ss -antlpH | awk 'BEGIN{count=0} {count } END{print count}') ##所有处于 ESTABLISHED 状态的TCP连接个数 TCP_Estab_Total=$(ss -antpH | awk 'BEGIN{count=0} /^ESTAB/{count } END{print count}') ##所有处于 TIME-WAIT 状态的 tcp 连接个数 TCP_TIME_WAIT_Total=$(ss -antpH | awk 'BEGIN{count=0} /^TIME-WAIT/{count } END{print count}') ##显示TCP连接总数 echo "TCP连接总数:$TCP_Total" ##显示UDP连接总数 echo "UDP连接总数:$UDP_Total" ##显示处于LISTEN状态的TCP端口个数 echo "处于LISTEN状态的TCP端口个数:$TCP_Listen_Total" ##显示处于ESTABLISHED状态的TCP连接个数 echo "处于ESTAB状态的TCP连接个数:$TCP_Estab_Total" ##显示处于TIME-WAIT状态的TCP连接个数 echo "处于TIME-WAIT状态的TCP连接个数:$TCP_TIME_WAIT_Total" [root@liruilong ~]# sh /root/shell/day05/net.sh TCP连接总数:15 UDP连接总数:10 处于LISTEN状态的TCP端口个数:15 处于ESTAB状态的TCP连接个数:2 处于TIME-WAIT状态的TCP连接个数:0

循环嵌套

[root@liruilong ~]# mkdir /root/shell/day06 [root@liruilong ~]# vim /root/shell/day06/star.sh #!/bin/bash ####################### #此循环的作用是输出5个*在同一行 for i in {1..5} do echo -n "*" done echo echo ######################## #内层for循环在一行输出5个*;外层for循环,将内层循环执行5遍 for i in {1..5} do for j in {1..5} do echo -n "*" done echo done #####执行脚本 [root@liruilong ~]# sh /root/shell/day06/star.sh ***** ***** ***** ***** ***** *****

循环嵌套

打印星星矩阵

[root@liruilong ~]# mkdir -p /root/shell/day06 [root@liruilong ~]# vim /root/shell/day06/star.sh #!/bin/bash ####################### #此循环的作用是输出5个*在同一行 for i in {1..5} do echo -n "*" done echo echo ######################## #内层for循环在一行输出5个*;外层for循环,将内层循环执行5遍 for i in {1..5} do for j in {1..5} do echo -n "*" done echo done

#####执行脚本 [root@liruilong ~]# sh /root/shell/day06/star.sh ***** ***** ***** ***** ***** *****

排列与组合

[root@liruilong ~]# vim /root/shell/day06/compose.sh #!/bin/bash ###打印1-3的所有两位数的排列组合方式 for i in {1..3} do for j in {1..3} do echo "${i}${j}" done done

打印形状

[root@liruilong ~]# vim /root/shell/day06/sharp1.sh #!/bin/bash ####打印出上述图片形状 for((i=1;i<=6;i )) do for((j=1;j<=i;j )) do echo -ne "\033[46m \033[0m" done echo done ############ [root@liruilong ~]# vim /root/shell/day06/sharp2.sh #!/bin/bash ####打印出上述图片形状 for((i=1;i<=6;i )) do for((j=6;j>=i;j--)) do echo -ne "\033[46m \033[0m" done echo done

带菜单的脚本

[root@liruilong ~]# vim /root/shell/day06/menu.sh #!/bin/bash echo "1.查看剩余内存容量." echo "2.查看根分区剩余容量." echo "3.查看cpu十五分钟负载." echo "4.查看系统进程数量." echo "5.查看系统账户数量." echo "6.退出." ###while死循环,查看过程不退出,不需要继续查看可以按6选择退出 while : do read -p "请输入选项[1-6]:" key ###case语句,对用户输入key进行判断给出相应的结果 case $key in 1) free| awk '/Mem/{print $NF}';; 2) df | awk '/\/$/{print $4}';; 3) uptime | awk '{print $NF}';; 4) ps -aux | wc -l;; 5) sed -n '$=' /etc/passwd;; 6) exit;; esac done

备份数据备份日志

[root@liruilong ~]# vim /root/shell/day06/bak_log.sh #!/bin/bash ###此脚本运用日期定义备份的文件名,方便与每天进行备份不重复 date=`date "%Y%m%d"` if [ ! -f /tmp/log-$date.tar.gz ];then tar -zcPf /tmp/log-$date.tar.gz /var/log fi ###执行脚本并检查输出结果 [root@liruilong ~]# sh /root/shell/day06/bak_log.sh [root@liruilong ~]# ls /tmp/log-* /tmp/log-20200718.tar.gz

备份数据库

###安装mariadb数据库,重启服务 [root@liruilong ~]# yum -y install mariadb mariadb-server [root@liruilong ~]# systemctl restart mariadb ####查看数据库服务的进程信息 [root@liruilong ~]# ss -ntulpa | grep mysql tcp LISTEN 0 50 *:3306 *:* users:(("mysqld",pid=9561,fd=14)

##mysqldump可以对数据库中的库进行备份 ##格式: mysqldump -u"用户名" --password="" 数据库名 > 备份名.sql [root@liruilong ~]# mysqldump mysql > mysql.sql

[root@liruilong ~]# vim /root/shell/day06/mysqldump.sh #!/bin/bash ###date 指定备份数据名;iuser 指定登录数据库的用户 ###ipass 指定登录密码,默认为空;db 指定要备份的数据库 date=$(date "%Y%m%d") iuser=root ipass= db=mysql ###文件在/tmp 下不存在时才会进行备份 if [ ! -f /tmp/$db-$date.sql ];then mysqldump -u$iuser --password="$ipass" $db > /tmp/$db-$date.sql fi

###运行脚本 [root@liruilong ~]# sh /root/shell/day06/mysqldump.sh [root@liruilong ~]# ls -l /tmp/mysql-* -rw-r--r-- 1 root root 514619 7月 18 12:54 /tmp/mysql-20200718.sql

[root@liruilong ~]# vim /root/shell/day06/bak_mysql.sh #!/bin/bash ###对数据库中的mysql库下每一个表都进行打包备份;备份文件存放在/tmp/mysql目录下 date=$(date "%Y%m%d") db_dir="/var/lib/mysql" db=mysql [ ! -d /tmp/$db ] && mkdir /tmp/$db for i in $(ls $db_dir/$db) do tar -zcf /tmp/$db/$i-$date.tar.gz $db_dir/$db/$i done ###运行脚本 [root@liruilong ~]# sh /root/shell/day06/bak_mysql.sh [root@liruilong ~]# ls /tmp/mysql

mysql> show databases -> ; -------------------- | Database | -------------------- | information_schema | | mysql | | performance_schema | | sys | -------------------- 4 rows in set (0.00 sec) mysql> create databases liruilong; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'databases liruilong' at line 1 mysql> create database liruilong; Query OK, 1 row affected (0.02 sec) mysql> use liruilong; Database changed mysql> create table demo(id int(2),name varchar(20)); Query OK, 0 rows affected (0.04 sec) mysql>

差异备份

嗯,这个有些复杂。。。

部署安装 inotifywait 监听软件

[root@liruilong ~]# yum -y install gcc make #准备源码安装环境 [root@liruilong ~]# tar -xvf tools.tar.gz #解压tar包到当前目录下 ##源码安装必须先进入到源码包目录下 [root@liruilong ~]# cd /root/inotify-tools-3.13/ [root@liruilong inotify-tools-3.13]# ./configure [root@liruilong inotify-tools-3.13]# make && make install #编译安装 [root@liruilong inotify-tools-3.13]# ##安装成功后会生成两个命令 [root@liruilong inotify-tools-3.13]# ls /usr/local/bin/ inotifywait inotifywatch

部署httpd服务

##安装apache的服务 [root@liruilong ~]# yum -y install httpd ##重启服务 [root@liruilong ~]# systemctl restart httpd ##查看apache的端口号 [root@liruilong ~]# netstat -ntulpa | grep httpd tcp6 0 0 :::80 :::* LISTEN 15364/httpd ##安装apache的服务 [root@node ~]# yum -y install httpd ##重启服务 [root@node ~]# systemctl restart httpd ##查看apache的端口号 [root@node ~]# netstat -ntulpa | grep httpd tcp6 0 0 :::80 :::* LISTEN 15364/httpd

生成密钥,发送到 node上

####非交互式生成密钥 [root@liruilong ~]# ssh-keygen -N '' -f /root/.ssh/id_rsa ###发送公钥到虚拟机pc207上 [root@liruilong ~]# ssh-copy-id root@192.168.4.207

差异备份【inotify rsync】

[root@liruilong ~]# vim /root/shell/day06/isync.sh #!/bin/bash ##from_dir 为要被同步的目录 from_dir="/var/www/html/" ##将$from_dir下的内容,同步到服务器192.168.4.207的/var/www/html/目录下 rsync_cmd="rsync -az --delete $from_dir root@192.168.4.207:/var/www/html/" ##inotifywait监听 $from_dir 目录,目录下发生文件的变化时,执行同步操作,脚本后台运行 while inotifywait -rqq -e modify,move,create,delete,attrib $from_dir do $rsync_cmd done

###执行脚本,查看后台进程 [root@liruilong ~]# sh /root/shell/day06/isync.sh & [1] 16532 [root@liruilong ~]# jobs -l [1] 9314 运行中 sh /root/shell/day06/rsync.sh & ###验证结果 [root@liruilong ~]# cp /etc/passwd /var/www/html/ [root@liruilong ~]# ssh root@192.168.4.207 "ls /var/www/html" html passwd

安全脚本HASH值HASH值

######文件的内容只要不发生变化,HASH值就是唯一的 ##计算文件的hash值 [root@liruilong ~]# md5sum /etc/passwd 6218010e73619a856999d39590a533f8 /etc/passwd ##只要文件内容不变,hash值一样 [root@liruilong ~]# cp /etc/passwd /root/pass [root@liruilong ~]# md5sum /root/pass 6218010e73619a856999d39590a533f8 /root/pass ##删除了文件第5行,内容发生变化,hash值改变 [root@liruilong ~]# sed -i '5d' /root/pass [root@liruilong ~]# md5sum /root/pass 449a721dd0449390377ae5216922faa7 /root/pass ###sha256sum和sha512sum都是计算hash值的,区别是长度不同 [root@liruilong ~]# sha256sum /etc/passwd db5560c8d21a9a4558272a2781ed1636eb40e7ebd709d5bca6751eb09db43383 /etc/passwd [root@liruilong ~]# sha512sum /etc/passwd c42b1c3531cd9d45c669845906f033c19cb40d626febdccd1e4834f1feb40730e4d52e0317dfd3f5 7f7406a23c10901be8d65787398beeae4513d71838f34803 /etc/passwd

数据安全检测脚本

[root@liruilong ~]# vim /root/shell/day06/data.sh #!/bin/bash ###为/etc/下所有以 .conf 结尾的文件生成hash值,保存到/tmp/data.log文件中 for i in $(ls /etc/*.conf) do md5sum $i >> /tmp/data.log done

##运行脚本,查看结果 [root@liruilong ~]# sh /root/shell/day06/data.sh [root@liruilong ~]# cat /tmp/data.log

SSH配置sshd配置

sshd主配置文件:

linux命令与shell脚本命令大全(等知识的一些笔记)(7)

###拷贝远程服务 sshd 的主配置文件 [root@liruilong ~]# cp /etc/ssh/sshd_config /opt/ [root@liruilong ~]# ls -l /opt/sshd_config -rw------- 1 root root 3907 7月 20 10:00 /opt/sshd_config ###过滤包含 port 的行 [root@liruilong ~]# grep -i "port" /opt/sshd_config ###使用sed删除对应行的注释 [root@liruilong ~]# sed -n '/^#Port/s/#//p' /opt/sshd_config Port 22 ###过滤包含 permitrootlogin 的行 [root@liruilong ~]# grep -i 'permitrootlogin' /opt/sshd_config ###使用sed删除对应行的注释 [root@liruilong ~]# sed -n '/^#PermitRootLogin/s/#//p' /opt/sshd_config PermitRootLogin yes ###过滤包含 usedns 的行 [root@liruilong ~]# grep -i "usedns" /opt/sshd_config ###使用sed删除对应行的注释 [root@liruilong ~]# sed -n '/^#UseDNS/s/#//p' /opt/sshd_config UseDNS yes ###上述操作只是打印出来,-i 直接修改配置文件 [root@liruilong ~]# sed -i '/^#Port/s/#//' /opt/sshd_config [root@liruilong ~]# sed -i '/^#PermitRootLogin/s/#//' /opt/sshd_config [root@liruilong ~]# sed -i '/^#UseDNS/s/#//' /opt/sshd_config

[root@liruilong ~]# vim /root/shell/day06/ssh_conf.sh #!/bin/bash ####安全的远程配置脚本 conf="/opt/sshd_config" sed -i '/^Port/s/22/1122/' $conf sed -i '/^PermitRootLogin/s/yes/no/' $conf sed -i '/^UseDNS/s/yes/no/' $conf sed -i '$a AllowUsers tom' $conf systemctl restart sshd

###运行脚本 [root@liruilong opt]# sh /root/shell/day06/ssh_conf.sh ###查看结果 [root@liruilong ~]# sed -n '/^Port/p' /opt/sshd_config Port 1122 [root@liruilong ~]# sed -n '/^PermitRootLogin/p' /opt/sshd_config PermitRootLogin no [root@liruilong ~]# sed -n '/^UseDNS/p' /opt/sshd_config UseDNS no [root@liruilong ~]# sed -n '$p' /opt/sshd_config AllowUsers tom

、格式化输出passwd格式输出格式化输出各式化输出/etc/passwd,效果如下 :

###打印 用户名,UID和家目录 [root@liruilong ~]# awk -F: 'BEGIN{print "用户名 UID 家目录"} {print $1,$3,$6}' /etc/passwd 用户名 UID 家目录 root 0 /root bin 1 /bin daemon 2 /sbin ...... ###column -t 作用是对打印的内容进行排版 [root@liruilong ~]# awk -F: 'BEGIN{print "用户名 UID 家目录"} {print $1,$3,$6}' /etc/passwd | column -t 用户名 UID 家目录 root 0 /root bin 1 /bin daemon 2 /sbin

过滤系统账户对应的密码

###定义变量 hello [root@liruilong ~]# hello="nihao" ### -v 选项,可以引用shell中的变量,将变量hello的值赋予tmp [root@liruilong ~]# awk -v tmp=$hello 'BEGIN{print tmp}' nihao

[root@liruilong ~]# sh /root/shell/day06/userpass.sh #!/bin/bash ###过滤出以bash结尾的用户,赋予变量USER USER=$(awk -F: '/bash$/{print $1}' /etc/passwd) for i in $USER do awk -F: -v iuser=$i '$1==iuser{print $1,$2}' /etc/shadow done ##注意单独使用时,$1=="root",要加双引号,代表字符串 ## awk -F: '$1=="root"{print $1,$2}' /etc/shadow

linux命令与shell脚本命令大全(等知识的一些笔记)(8)

在这里插入图片描述

###运行脚本 [root@liruilong ~]# sh /root/shell/day06/userpass.sh root $6$pAL3P7fovbgv4LEv$zwO6BZTMSfyfFcIZHO8S.TQc8RDuBtj4dj3wJ5CdH0clUue3G15.0C0PpytA wh9Lo.Dcxl1q0j6.z09yOGH32/ zhangzhao $6$mcBYSo/SxmOFm8l.$NxqB4us2UerMMPRPHn4u2v4BdFqkPBza/5NA1IV/Z3.knseF7sNS8.171OPx KULoW7KBYY6qyM0VNxF2r6I.h0

、综合案例一键PXE kickstartPXE:

linux命令与shell脚本命令大全(等知识的一些笔记)(9)

在这里插入图片描述

1、启动步骤详解

1、服务器加电启动,从DHCP服务器获取IP地址并加载(PXEClient)。 2、通过TFTP服务器获取网络引导程序(pxelinux.0)。 3、引导程序读取配置文件(pxelinux.cfg本例中文件名为:default)。 4、引导程序加载文件系统初始化(initrd)程序和内核初始镜像(vmlinuz)、自动应答程序(ks.cfg)。 5、按自动应答文件中指定的网络安装方式,以FTP方式安装linux系统。

一键PXE kickstart

###输出多行文本 [root@liruilong ~]# cat << EOF > hello world > i am come here > i love the world > EOF hello world i am come here i love the world ###将多行文本保存到文件/opt/password中 [root@liruilong ~]# cat > /opt/password << EOF > hello world > i am come here > i love the world > EOF ###查看文件内容跟 [root@liruilong ~]# cat /opt/password hello world i am come here i love the world [root@liruilong ~]# vim /root/shell/day06/pxe.sh #!/bin/bash ##定义变量,让方便后面的调用,和提高适用性 DHCP_NET=192.168.4.0 DHCP_NETMASK=255.255.255.0 DHCP_MINIP=192.168.4.100 DHCP_MAXIP=192.168.4.200 DHCP_ROUTER=192.168.4.254 DHCP_NEXT_SERVER=192.168.4.5 HTTP_IP=192.168.4.5 ##安装软件包 yum -y install httpd dhcp tftp-server syslinux ##临时停用SELinux setenforce 0 ##配置 DHCP 服务 cat > /etc/dhcp/dhcpd.conf << EOF subnet $DHCP_NET netmask $DHCP_NETMASK { range $DHCP_MINIP $DHCP_MAXIP; option routers $DHCP_ROUTER; default-lease-time 600; max-lease-time 7200; next-server $DHCP_NEXT_SERVER; filename "pxelinux.0"; } EOF systemctl restart dhcpd systemctl enable dhcpd ##配置httpd共享服务器 if [ ! -e /dev/cdrom ];then echo "未检测到系统光盘/dev/cdrom,请插入光盘后再试" exit fi [ -d /var/www/html/cdrom ] || mkdir /var/www/html/cdrom mount /dev/cdrom /var/www/html/cdrom systemctl start httpd ##配置kickstart 文件 cat > /var/www/html/ks.cfg << EOF install keyboard 'us' rootpw --plaintext redhat url --url="http://$HTTP_IP/cdrom" lang en_US firewall --disabled auth --useshadow --passalgo=sha512 text selinux --disabled network --bootproto=dhcp --device=eth0 reboot timezone Asia/Shanghai bootloader --location=mbr zerombr clearpart --all --initlabel part /boot --fstype="xfs" --size=500 part / --fstype="xfs" --grow --size=1 %packages @base %end EOF ####配置tftp服务 cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/ cp /var/www/html/cdrom/isolinux/* /var/lib/tftpboot/ [ -d /var/lib/tftpboot/pxelinux.cfg ] || mkdir /var/lib/tftpboot/pxelinux.cfg ##部署菜单文件 cat > /var/lib/tftpboot/pxelinux.cfg/default << EOF default vesamenu.c32 timeout 100 label linux menu label ^Install CentOS 7 kernel vmlinuz append initrd=initrd.img ks=http://$HTTP_IP/ks.cfg EOF systemctl start tftp ##临时清空防火墙规则 iptables -F ###执行脚本 [root@liruilong ~]# sh /root/shell/day06/pxe.sh ###检查三个服务【dhcpd,httpd,tftp】是否已经运行 [root@liruilong ~]# systemctl status dhcpd | grep Active Active: active (running) since 一 2020-07-20 12:06:31 CST; 16min ago [root@liruilong ~]# systemctl status tftp | grep Active Active: active (running) since 一 2020-07-20 12:05:35 CST; 17min ago [root@liruilong ~]# systemctl status httpd | grep Active Active: active (running) since 一 2020-07-20 12:05:34 CST; 17min ago

,