关于Linux中shell 等知识的一些笔记
写在前面
- 笔记是上课后整理的笔记,适合温习,不适合新手,希望对小伙伴有帮助
- 笔记内容包括:Shell一些常见情境
傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波
shell 是用户 与 Linux 内核之间的解释器
区分 shell 和 bash:shell是解释器的总称,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 ~]$
- 快捷键、Tab键补齐
Ctrl + A
#将光标移动到命令行首Ctrl + E
#将光标移动到命令行尾Ctrl + C
#中断正在执行的命令Ctrl + L
#清屏Ctrl + W
#从光标位置,往回删一个单词Ctrl + U
#从光标位置,往回删到开头
- 命令历史 ( history )
[root@liruilong ~]$ history #查看历史记录
[root@liruilong ~]$ history -c #清空历史记录
[root@liruilong ~]$ vim /etc/profile #修改历史记录的数量
46 HISTSIZE=1000
- 命令别名 (alias)
[root@liruilong ~]$ alias #查看当前用户可以使用的别名
[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'
正确输出重定向覆盖,> 等同于 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 解释器:
/etc/shadow
什么是 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"
方法一:需要为文件赋予可执行的权限 |
---|
绝对路径执行 |
相对路径执行 |
[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 查看进程树 |
[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
[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
以固定的名称,存放可以能有变化的值
- 定义变量的格式:变量名=变量值
- 取消变量的格式:unset 变量名
注意事项: |
---|
= 两边不能有空格,不要使用关键字做变量名,如: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 #再次输出结果为空
变量类型 |
---|
环境变量(变量名通常大写,有操作系统维护); |
位置变量(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:所有的身份验证令牌已经成功更新。
预定义变量 |
---|
用来保存脚本程序的执行信息 |
直接使用这些变量 |
不能直接为这些变量赋值 |
[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 ~]$
区别三种定界符 | – |
---|---|
双引号 " " | 允许扩展,以 $ 引用其他变量; |
单引号 ’ ’ | 禁用扩展,即便 $ 也视为普通符号; |
反引号 `` | 将命令的执行输出作为变量值,$() 与反引号等效; |
[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 ~]#
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: 鉴定令牌操作错误
变量的作用范围 | – |
---|---|
局部变量 | 新定义的变量默认只是在当前 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
......
基本运算法则 |
---|
四则运算 |
加法:num1 + num2 |
减法:num1 - num2 |
乘法:num1 * num2 |
整除:num1 / num2 |
取余数运算 |
求模:num1 % num2 |
- 使用
$[ ]
或$(( ))
表达式- 格式:$[整数1 运算符 整数2…]
- 计算结果替换表达式本身,可结合 echo 命令输出
[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 用于指定算术运算
[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
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 结果小数位保留两位
- bc 支持的比较操作符:
>、>=、<、<=、==、!=
- 表达式成立则返回1,否则返回0
[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 ~]#
- -n选项:不换行
- -e选项:支持扩展属性
- echo -e “\033[文字颜色m 文字 \033[0m”
- 文字颜色:30 ----------- 37
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
[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
[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
- 替换1个结果:${变量/旧字串/新字串}
- 替换全部结果:${变量//旧字串/新字串}
子串替换时,变量本身的值并不会变化,只会把变化的值输出到屏幕
###子串替换时,变量本身的值并不会变化,只会把变化的值输出到屏幕
[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指令 |
---|
p(print): 打印行 |
d(delete): 删除行 |
c(replace): 替换行 |
s(substitution): 替换关键词 |
=:打印行号 |
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
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
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
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
i (insert): 插入
a (append): 追加
r (read): 读 取文件 | 导入文件内容
w (write): 文件另存为 | 导出文件内容
##查看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
##在第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
##将/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
##将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
点名器
awk 编程语言/数据处理引擎
创造者:Aho、Weinberger、Kernighan
基于模式匹配检查输入文本,逐行处理并输出
通常用于在 Shell 脚本中,获取指定的数据
单独用时,可对文本数据做统计
格式1:前置命令| awk [选项] , [条件] (指令)’
格式2: awk [选项] ’ [条件] {指令}, 文件…
格式3: awk ,BEGIN{} [条件]{} END{}’ 文件…
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
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
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 ~]#
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
数组的下标可以是数字,也可以是字符串
###给数组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 ~]#
[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
- 物理备份(buttaidong)
[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>
嗯,这个有些复杂。。。
[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
####非交互式生成密钥
[root@liruilong ~]# ssh-keygen -N '' -f /root/.ssh/id_rsa
###发送公钥到虚拟机pc207上
[root@liruilong ~]# ssh-copy-id root@192.168.4.207
[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 值与文件名称、时间、大小等信息无关,仅与内容有关
- MD5
- SHA256
######文件的内容只要不发生变化,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
sshd主配置文件:
- Port 3389 // 改用非标准端口
- PermitRootLogin no // 禁止root登录
- UseDNS no //不解析客户机地址
- AllowUsers 账户名 //设置远程连接的白名单,多个用户空格分割
###拷贝远程服务 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
###打印 用户名,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
- 在 awk中可以通过 -v 选项调用 shell 中的变量
###定义变量 hello
[root@liruilong ~]# hello="nihao"
### -v 选项,可以引用shell中的变量,将变量hello的值赋予tmp
[root@liruilong ~]# awk -v tmp=$hello 'BEGIN{print tmp}'
nihao
- 从 /etc/passwd 中将所有能登陆的账户名提取出来
- 从 /etc/shadow 中提取账户对应的密码
[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
###运行脚本
[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,全名Pre-boot Execution Environment,预启动执行环境;
- 通过网络接口启动计算机,不依赖本地存储设备(如硬盘)或本地已安装的操作系统;由Intel和Systemsoft公司于1999年9月20日公布的技术;
- lient/Server的工作模式;PXE客户端会调用网际协议(IP)、用户数据报协议(UDP)、动态主机设定协议(DHCP)、小型文件传输协议(TFTP)等网络协议;
- PXE客户端(client)这个术语是指机器在PXE启动过程中的角色。一个PXE客户端可以是一台服务器、笔记本电脑或者其他装有PXE启动代码的机器(我们电脑的网卡)。
1、服务器加电启动,从DHCP服务器获取IP地址并加载(PXEClient)。
2、通过TFTP服务器获取网络引导程序(pxelinux.0)。
3、引导程序读取配置文件(pxelinux.cfg本例中文件名为:default)。
4、引导程序加载文件系统初始化(initrd)程序和内核初始镜像(vmlinuz)、自动应答程序(ks.cfg)。
5、按自动应答文件中指定的网络安装方式,以FTP方式安装linux系统。
- 部署 PXE+kickstart 环境
- dhcp 服务
- tftp 服务
- http 服务
- 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
- 点赞
- 收藏
- 关注作者
评论(0)