项目实战集
ping命令
Linux ping 命令用于检测主机。
执行 ping 指令会使用 ICMP 传输协议,发出要求回应的信息,若远端主机的网络功能没有问题,就会回应该信息,因而得知该主机运作正常。
-d 使用Socket的SO_DEBUG功能。
-c <完成次数> 设置完成要求回应的次数。
-f 极限检测。
-i<间隔秒数> 指定收发信息的间隔时间。
-I<网络界面> 使用指定的网络接口送出数据包。
-l<前置载入> 设置在送出要求信息之前,先行发出的数据包。
-n 只输出数值。
-p<范本样式> 设置填满数据包的范本样式。
-q 不显示指令执行过程,开头和结尾的相关信息除外。
-r 忽略普通的Routing Table,直接将数据包送到远端主机上。
-R 记录路由过程。
-s<数据包大小> 设置数据包的大小。
-t<存活数值> 设置存活数值TTL的大小。
-v 详细显示指令的执行过程。
-w <deadline> 在 deadline 秒后退出。
服务器状态检测脚本
使用for循环判断主机是否存活:
#!/bin/bash
ip_list="192.168.1.1 127.0.0.1 0.0.0.0"
for ip in $ip_list
do
for count in {1..3};do
ping -c1 -w1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "[成功] $ip 通讯正常"
break
fi
done
if [ $count -eq 3 ];then
echo "[失败] $ip 通讯失败"
fi
done
使用while循环判断主机是否存活:
#!/bin/bash
#ip_list="192.168.1.1 127.0.0.1 0.0.0.0"
while read ip
do
count=1
while [ $count -le 3 ];do
ping -c1 -w1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "[成功] $ip 通讯正常"
break
fi
count=$(($count+1))
done
if [ $count -eq 4 ];then
echo "[失败] $ip 通讯失败"
fi
done <ip.txt
xargs命令
xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。
xargs可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。
常用选项
-d <定界符>:指定输入项的定界符,默认为换行符。
-I <占位符>:指定替代字符串,用于替换命令中的参数位置。
-n <数量>:指定每次执行的参数数量。
-t:显示实际执行的命令。
-p:提示用户确认是否执行命令
通过cat命令理解xargs用法
原始文件
root@sh:~# cat file.txt file1 file2 file3通过管道符号讲标准输出转换为标准输入传递给cat
root@sh:~# cat file.txt|cat file1 file2 file3通过管道符号和xargs将标准输出转换为参数传递给cat
root@sh:~# cat file.txt|xargs cat cat: file1: 无法访问: 没有那个文件或目录 (No such file or directory) cat: file2: 无法访问: 没有那个文件或目录 (No such file or directory) cat: file3: 无法访问: 没有那个文件或目录 (No such file or directory)
常见用法
查找并打包日志
find . -name "*.log" |xargs tar -cvzf log.tar.gz对日志文件进行文字查找
find . -name "*.log" |xargs grep -n "error"批量创建目录
find /var/log -maxdepth 1 -type d |xargs -I {} mkdir .{}
uniq命令
Linux uniq命令用于检查及删除文本文件中重复出现的行列,一般与 sort 命令结合使用。
uniq命令可检查文本文件中重复出现的行列。
-c或--count 在每列旁边显示该行重复出现的次数。
-d或--repeated 仅显示重复出现的行列。
-f<栏位>或--skip-fields=<栏位> 忽略比较指定的栏位。
-s<字符位置>或--skip-chars=<字符位置> 忽略比较指定的字符。
-u或--unique 仅显示出一次的行列。
-w<字符位置>或--check-chars=<字符位置> 指定要比较的字符。
--help 显示帮助。
--version 显示版本信息。
[输入文件] 指定已排序好的文本文件。如果不指定此项,则从标准读取数据;
[输出文件] 指定输出的文件。如果不指定此选项,则将内容显示到标准输出设备(显示终端)
文本文件包含以下内容:
Copy code
apple
banana
apple
orange
orange
apple
使用uniq -c命令来统计重复行的次数:
$ uniq -c data.txt
1 apple
1 banana
2 apple
2 orange
1 apple
输出的每一行都包含两部分:重复行的次数和该行的内容。在上面的示例中,第一行的apple只出现了一次,第二行的banana只出现了一次,第三行的apple出现了两次,以此类推。
Nginx日志参数
| 变量名称 | 变量描述 | 举例说明 |
|---|---|---|
| $remote_addr | 客户端地址 | 113.140.15.90 |
| $remote_user | 客户端用户名称 | – |
| $time_local | 访问时间和时区 | 18/Jul/2012:17:00:01 +0800 |
| $request | 请求的URI和HTTP协议 | “GET /pa/img/home/logo-alipay-t.png HTTP:/1.1″ |
| $http_host | 请求地址,即浏览器中你输入的地址(IP或域名) | img.alipay.com10.253.70.103 |
| $status | HTTP请求状态 | 200 |
| $upstream_status | upstream状态 | 200 |
| $body_bytes_sent | 发送给客户端文件内容大小 | 547 |
| $http_referer | 跳转来源 | “https://cashier.alip/ay.com…/” |
| $http_user_agent | 用户终端代理 | “Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; GTB7.0; .NET4.0C; |
| $ssl_protocol | SSL协议版本 | TLSv1 |
| $ssl_cipher | 交换数据中的算法 | RC4-SHA |
| $upstream_addr | 后台upstream的地址,即真正提供服务的主机地址 | 10.228.35.247:80 |
| $request_time | 整个请求的总时间 | 0.205 |
| $upstream_response_time | 请求过程中,upstream响应时间 | 0.002 |
将以下内容保存到access.log文件中作为练习的日志文件:
192.168.1.1 - - [18/Jul/2023:10:15:32 +0800] "GET /index.html HTTP/1.1" 200 2326 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.2 - - [18/Jul/2023:10:15:35 +0800] "GET /about.html HTTP/1.1" 200 1452 "https://example.com/index.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.3 - - [18/Jul/2023:10:15:40 +0800] "GET /contact.html HTTP/1.1" 404 196 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" 192.168.1.1 - - [18/Jul/2023:10:16:02 +0800] "GET /products.html HTTP/1.1" 200 3201 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.4 - - [18/Jul/2023:10:16:10 +0800] "GET /api/data HTTP/1.1" 200 512 "https://example.com/products.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.2 - - [18/Jul/2023:10:16:15 +0800] "GET /favicon.ico HTTP/1.1" 200 4286 "https://example.com/about.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.5 - - [18/Jul/2023:10:16:20 +0800] "GET /admin/login HTTP/1.1" 403 1024 "-" "Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36" 192.168.1.3 - - [18/Jul/2023:10:16:25 +0800] "POST /submit-form HTTP/1.1" 302 0 "https://example.com/contact.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15" 192.168.1.1 - - [18/Jul/2023:10:16:30 +0800] "GET /style.css HTTP/1.1" 200 1234 "https://example.com/index.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.6 - - [18/Jul/2023:10:16:35 +0800] "GET /script.js HTTP/1.1" 200 876 "https://example.com/products.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.2 - - [18/Jul/2023:10:16:40 +0800] "GET /images/logo.png HTTP/1.1" 200 5432 "https://example.com/about.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.4 - - [18/Jul/2023:10:16:45 +0800] "GET /api/user HTTP/1.1" 401 256 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.5 - - [18/Jul/2023:10:16:50 +0800] "GET /robots.txt HTTP/1.1" 200 123 "-" "Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36" 192.168.1.1 - - [18/Jul/2023:10:17:00 +0800] "GET /index.html HTTP/1.1" 200 2326 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 192.168.1.7 - - [18/Jul/2023:10:17:05 +0800] "GET /404.html HTTP/1.1" 404 196 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1"统计访问量最高的IP(sort + uniq)
cat access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -10 解析: awk '{print $1}':提取日志中的IP($remote_addr) sort:排序,使相同IP相邻 uniq -c:统计每个IP出现的次数 sort -nr:按访问量降序排序 head -10:显示前10个查找HTTP状态码分布(awk + sort + uniq)
cat access.log | awk '{print $9}' | sort | uniq -c | sort -nr 解析: awk '{print $9}':提取$status(HTTP状态码) sort | uniq -c:统计各状态码出现次数 sort -nr:按频率排序统计最频繁访问的URL(awk + sort + uniq)
cat access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -20 解析: awk '{print $7}':提取$request中的URL sort | uniq -c:统计URL访问次数 head -20:显示前20个热门URL查找耗时最长的请求(sort + xargs)
cat access.log | sort -k10 -nr | head -5 | awk '{print "URL:", $7, "Time:", $10}' 解析: sort -k10 -nr:按$request_time(第10列)降序排序 head -5:显示最慢的5个请求 awk:格式化输出URL和耗时批量查找包含404错误的日志文件(xargs + grep)
find /var/log/nginx/ -name "*.log" | xargs grep -n " 404 "
多机部署MySQL
实验环境搭建
本项目通过docker搭建实验环境,首先需要在
centos7虚拟机中安装docker
运行以下命令安装Docker# 安装依赖 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # 设置阿里镜像源 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 安装最新版本docker sudo yum install -y docker-ce # 启动docker sudo systemctl start docker sudo systemctl enable docker # 查看docker状态 sudo systemctl status docker获取并导入镜像
使用WinSCP传入虚拟机
导入镜像
# 导入镜像 docker load -i openssh.tar
通过镜像
linuxserver/openssh-server创建多个主机创建主机1,默认ssh端口号2222,主机名设置为host1,外部ssh端口号2221
sudo docker run -d --name host1\ -e PASSWORD_ACCESS=true \ -e USER_PASSWORD=password \ -e USER_NAME=demo \ -p 2221:2222 linuxserver/openssh-server:latest创建主机2,默认ssh端口号2222,主机名设置为host2,外部ssh端口号2222
sudo docker run -d --name host2 \ -e PASSWORD_ACCESS=true \ -e USER_PASSWORD=password \ -e USER_NAME=demo \ -p 2222:2222 linuxserver/openssh-server:latest创建主机3,默认ssh端口号2222,主机名设置为host3,外部ssh端口号2223
sudo docker run -d --name host3 \ -e PASSWORD_ACCESS=true \ -e USER_PASSWORD=password \ -e USER_NAME=demo \ -p 2223:2222 linuxserver/openssh-server:latest
通过
sudo docker ps查看容器信息容器常用命令
## 查看当前运行的容器状态 sudo docker ps ## 停止容器 sudo docker stop 容器名 ## 删除容器 sudo docker rm 容器名 ## 进入正在运行的容器 sudo docker exec -it 容器名 /bin/bash ##从容器中退出 exit或者使用快捷键CTRL + p 然后CTRL + q通过
telnet localhost 2221验证centos和容器之间的网络通过
ssh -p 2221 demo@localhost验证ssh服务,使用用户名demo和密码password登录容器,在容器内使用exit断开ssh连接。
推送公钥到各个主机
ssh密钥登录原理
我们一般使用 PuTTY 等 SSH 客户端来远程管理 Linux 服务器。但是,一般的密码方式登录,容易有密码被暴力破解的问题。所以,一般我们会将 SSH 的端口设置为默认的 22 以外的端口,或者禁用 root 账户登录。其实,有一个更好的办法来保证安全,而且让你可以放心地用 root 账户从远程登录——那就是通过密钥方式登录。
密钥形式登录的原理是:利用密钥生成器制作一对密钥——一只公钥和一只私钥。将公钥添加到服务器的某个账户上,然后在客户端利用私钥即可完成认证并登录。
ssh-keygen制作密钥对ls ~/.ssh查看密钥文件ssh-copy-id -p 2221 demo@localhost推送公钥到目标主机ssh -p 2221 demo@localhost验证密钥登录
批量推送公钥
centos虚拟机安装expect工具
sudo yum install expectexpect是一个用于自动化交互式命令行工具的工具集,它可以用于编写脚本来处理需要与外部程序进行交互的场景。以下是expect常用的命令和用法:spawn:启动一个新的进程并与其进行交互。spawn ssh user@hostname上述命令将启动一个 SSH 连接,并与远程主机进行交互。
expect:匹配预期的输出或交互,并执行相应的操作。expect "password:" send "mypassword\r"上述命令会等待输出中出现 “password:”,然后发送密码。
send:向进程发送字符串。send "ls\r"上述命令会发送 “ls” 命令给进程。
批量推送公钥脚本
#!/bin/bash port_list="2221 2223" password="password" for i in $port_list do /usr/bin/expect -c " spawn ssh-copy-id -p $i demo@localhost expect { \"*connecting\" { send \"yes\r\"; exp_continue } } expect { \"*password\" { send \"$password\r\"; exp_continue } } expect eof " done
多机部署MySQL脚本
#!/bin/bash
port_list="2221 2222 2223"
password="password"
for i in $port_list
do
ping -c1 -w1 -p $i localhost
if [ $? -eq 0 ];then
/usr/bin/expect -c "
spawn ssh -p $i demo@localhost \"sudo apk add mysql mysql-client\"
expect {
\"*password\" { send \"$password\r\";exp_continue}}
expect eof
"
fi
done