shell优化
颜色
# linux命令行给字体加颜色 echo -e "\E[36myuanxiaojiang\E[0m" echo -e "\033[31myuanxiaojiang\033[0m" echo -e "\033[1;31myuanxiaojiang\033[0m" \E或\033:表示开启这种功能 [1;31m [效果;颜色m 1表示加粗 2表示正常 3表示倾斜 4表示加下划线 5表示闪烁 \E[0m或\033[0m:颜色设置结束 -e 识别转义字符
# 创建环境变量或写入脚本开头(永久使用写入/etc/profile) export RED="\E[5;31m" export GREEN="\E[1;32m" export BLUE="\E[1;34m" export END="\E[0m" echo -e "${RED}这是要加上颜色的内容啊${END}"
[root@m01 /server/scripts/devops-shell]# cat 12.sh #!/bin/bash redecho() { echo -ne "\E[5;31m" echo -n "$@" echo -e "\E[0m" } greenecho() { echo -ne "\E[5;32m" echo -n "$@" echo -e "\E[0m" } redecho $@ greenecho $@
gui
# dialog是Linux终端中创建图形用户界面的命令行工具
yum install -y dialog dialog --textbox /etc/hostname 80 80 dialog --textbox /etc/passwd 80 80 dialog --msgbox /etc/passwd 10 30
数组
概述
数组也是一种变量
# 数组名=() ${数组名[下标]} [root@m01 ~]# ip_array=(10.0.0.61 10.0.0.71 10.0.0.81) [root@m01 ~]# echo ${ip_array[0]} 10.0.0.61 # 输出数组中所有的值 [root@m01 ~]# echo ${ip_array[*]} 10.0.0.61 10.0.0.71 10.0.0.81 [root@m01 ~]# echo ${ip_array[@]} 10.0.0.61 10.0.0.71 10.0.0.81 # 输出数组中元素的个数 [root@m01 ~]# echo ${#ip_array[@]} 3 [root@m01 ~]# echo ${#ip_array[*]} 3
shell数组赋值
| shell数组创建(赋值) | 格式 | 应用场景 |
| 批量直接赋值 | array=(value1 value2 value3) | 应用最多 |
| 逐个元素赋值 | array[0]=value1 | 几乎不会使用 |
| read命令赋值 | read -p "输入数组中内容:" -a array (可以创建数组,用空格分隔) | 用于连续取数据 |
[root@m01 /yuan]# cat ip.txt 10.0.0.1 10.0.0.2 10.0.0.3 [root@m01 /yuan]# ip_list=(`cat ip.txt`) [root@m01 /yuan]# echo ${ip_list[@]} 10.0.0.1 10.0.0.2 10.0.0.3
案例:编写一个用户从键盘中输入10个整数,求其总和和平均值的脚本
[root@m01 /server/scripts/devops-shell]# cat 13.sh #!/bin/bash #1.vars sum=0 read -p "请输入10个整数:" -a num_list while [ ${#num_list[*]} -ne 10 ] do echo "输入的个数不正确,请重新输入:" read -a num_list done for i in ${num_list[@]} do if [[ $i =~ ^[0-9]+$ ]];then sum=$((${sum}+$i)) else echo "输入值格式错误" exit 1 fi done echo "sum=${sum}" echo "avg=$((${sum}/${#num_list[@]}))" echo "avg=$(echo "scale=2; ${sum}/${#num_list[@]}" |bc)"
Debug全流程
书写习惯
- 注释
- 变量
- 函数
- 返回值
- 参数与选项检查
- 输出
- 代码缩进
调试方法
- -x:sh/bash -x 显示详细的执行过程
- 精确显示过程:脚本使用functions函数库(脚本过大使用)
- set -x:开始显示详细过程
- set +x:终止显示详细过程
- 注释法:使用注释,缩小范围定位问题
- 输出关键变量
sed与变量
[root@m01 /yuan]# cat ip.txt 10.0.0.1 10.0.0.2 10.0.0.3 [root@m01 /yuan]# src=10.0.0 [root@m01 /yuan]# dst=192.16.1 [root@m01 /yuan]# sed "s#${src}#${dst}#g" ip.txt 192.16.1.1 192.16.1.2 192.16.1.3
awk
过滤
# 过滤出/etc/passwd第2行到第9行的第1列和第3列 [root@m01 ~]# awk -F':' 'NR>=2 && NR <=9 {print $1,$3}' /etc/passwd # 过滤出/etc/passwd用户名为root的最后一列内容 [root@m01 ~]# grep "^root:" /etc/passwd | awk -F':' '{print $NF}' [root@m01 ~]# awk -F':' '$1=="root" {print $NF}' /etc/passwd # 通过变量过滤出/etc/passwd用户名为root的最后一列内容 -v 用于在 awk 中定义变量,方便处理数据 [root@m01 ~]# awk -F':' -v n=$name '$1==n {print $NF}' /etc/passwd [root@m01 ~]# awk -F':' -v n=$name '$1~n {print $NF}' /etc/passwd # 过滤出网卡配置文件ip地址 [root@m01 ~]# awk -F'=' '/IPADDR/{print $2}' /etc/sysconfig/network-scripts/ifcfg-eth0
/模式匹配/
awk的判断(了解)
如果系统根分区磁盘使用率大于80,则提示磁盘空间不足
awk '{ if (condition) { action } }' filename
condition是你想要判断的条件。action是在条件为真时执行的操作
[root@m01 ~]# df -h |awk -F'[ %]+' '$NF=="/"{if ($(NF-1)>=80) print "磁盘空间不足"}'
[root@m01 ~]# df -h |awk -F'[ %]+' '$NF=="/" && $(NF-1)>=80 {print "磁盘空间不足"}'
[root@m01 ~]# awk 'BEGIN{for(i=1;i<=100;i++){sum=sum+i} print sum}'
5050 适合进行简单的固定范围计算,而不需要额外的输入数据
计算任意数字的总和
[root@m01 ~]# echo $num |awk '{for(i=1;i<=5;i++)sum=sum+$i;print sum}'
15 适合处理有结构的数据输入,但确保正确使用字段变量
awk数组
概述
awk数组专用于统计和分析
去重统计次数(sort + uniq)
去重求和
awk数组与shell数组的区别
awk数组:关联数组(下标是啥都行)
shell数组:普通数组(下标是数字)
使用
# 创建 [root@m01 ~]# awk 'BEGIN{array[0]=666;array["name"]="yuan"}' # 取值 [root@m01 ~]# awk 'BEGIN{array[0]=666;array["name"]="yuan";print array[0]}' 666
批量赋值
创建以url为下标,元素值为次数数组
[root@m01 ~]# cat /yuan/awk-array.txt img.yuanlinux.cn 6 bbs.yuanlinux.cn 7 avi.yuanlinux.cn 99 mp4.yuanlinux.cn 88 [root@m01 ~]# awk '{array[$1]=$2}END{for(url in array)print url,array[url]}' /yuan/awk-array.txt img.yuanlinux.cn 6 avi.yuanlinux.cn 99 bbs.yuanlinux.cn 7 mp4.yuanlinux.cn 88
案例:去重统计次数(分析文件中每个域名出现的次数)
[root@m01 ~]# cat /yuan/url.txt http://www.etiantian.org/index.html http://www.etiantian.org/1.html http://post.etiantian.org/index.html http://mp3.etiantian.org/index.html http://www.etiantian.org/3.html http://post.etiantian.org/2.html [root@m01 ~]# awk -F'/+' '{url[$2]=url[$2]+1}END{for(name in url)print name,url[name]}' /yuan/url.txt mp3.etiantian.org 1 www.etiantian.org 3 post.etiantian.org 2
[root@m01 ~]# awk -F'/+' '{url[$2]=url[$2]+1}END{for(name in url)print name,url[name]}' /yuan/url.txt |sort -rnk2 |head
www.etiantian.org 3
post.etiantian.org 2
mp3.etiantian.org 1
[root@web01 /var/log/nginx]# awk '{liu[$1]=liu[$1]+$10} END{for(ip in liu)print ip,liu[ip]}' /var/log/nginx/access.log-20250406 |sort -rnk2 |head 10.0.0.1 29365 10.0.0.6 650 10.0.0.5 0
awk与shell语法格式对比
| awk | shell | |
| if单分支判断 | if (条件) {命令;命令} |
if 条件;then
命令
fi
|
| if双分支判断 |
if (条件)
{命令}
else
{命令}
|
if 条件;then
命令
else
命令
fi
|
|
for循环:c语言形式
|
for(i=1;i<=10;iՎҡ)
{命令}
|
for((i=1;i<=10;iՎҡ))
do
命令
done
|
|
for循环:通用
|
awk专用于数组的循环
for( n in 数组名字)
print n(数组下标),数组名字[n]
|
for n in 清单
do
命令
done
|
command -v 是一个Shell内置命令,用于检查某个命令或程序是否存在于系统中,并返回该命令的路径。它的主要用途是验证可执行文件或Shell函数是否可以在当前环境中被找到。
[root@m01 /server/scripts/devops-shell]# command -v sshpass
/usr/bin/sshpass
[root@m01 /server/scripts/devops-shell]# echo $?
0
[root@m01 /server/scripts/devops-shell]# command -v sshpass_abc
[root@m01 /server/scripts/devops-shell]# echo $?
1
浙公网安备 33010602011771号