Linux——Shell编程笔记、监控一个主机状态、检测服务端口、查看内存和CUPtop10、安装nginx脚本(其他环境Java、Python、LAMP同理) 、创建用户01-20
Shell 脚本编写
命令 | 描述 | 命令 | 描述 | 命令 | 描述 | ||
---|---|---|---|---|---|---|---|
cd - | 前后位置切换 | ||||||
!! | 执行上一条命令 | ||||||
`` | 命令中执行命令 |
命令 | 参数 | 参数说明 | |||
---|---|---|---|---|---|
echo | -n | 不自动换行 | |||
-e | 先特别先执行\a \b \c \f \n \r \t \v | ||||
read | -s | 输入时隐藏 | |||
-t | 时间 | ||||
-n | 字符数限制 | ||||
-p | 输出 |
例子
- 代码颜色
echo -e "\033[背景色;字体颜色 字符串 \033[属性效果"
e.g.echo -e "\033[40;37m 带颜色的字体 \033[0m"
基础知识
变量
定义变量需要激活变量 source [文本位置]
- 全局变量
所有用户使用
定义export name='tom'
- 本地变量
当前用户使用 - 自定义变量
- 永久变量
定义在配置文件中如~/.bash_profile
,/etc/profile
定义变量 [逻辑名]=[数据]
取消变量 unset [变量名]
数组
语法:数组名字=(元素1 元素2 元素3 …)
输出数组:echo ${数组名字 [索引]}
赋值方法:数组名字[索引]=元素
访问数组:
访问全部数组 | echo ${数组名字 [@]} |
---|---|
统计数组元素个数 | echo ${#数组名字 [@]} |
获取数组元素索引 | echo ${!数组名字 [@]} |
从索引n开始访问m个元素 | echo ${数组名字 [@]:n:m} |
关联数组:
# 申明关联数组(字典)
declare —A name_array
name_array={[name]='yun' [age]='18'}
echo ${name_array[name]}
# 单个添加
name_array[height]='1.8m'
#输出
yun
if 判断语句
[ ] 下的算术运算
eq | 等于 | equal | ne | 不等于 | not equal | |
---|---|---|---|---|---|---|
gt | 大于 | greater than | ge | 大于等于 | greater than or equal | |
lt | 小于 | less than | le | 小于等于 | less than equal |
if语法:
if [ 判断条件 ] #例如:if [ $1 > $2 ]
then
输出
else
输出
fi
# 或
if (( 判断条件 )) #例如:if (( 3-2*3<1 ))
then
输出
else
输出
fi
# 或
array_test=('Tom' 'Alan' 'Alice' 'Leo' '')
for str in $array_test
do
if [[ $str == *o* ]] # 匹配搜索
then
echo "$str"
else
echo "no"
fi
done
# 如果没有目录就创建目录
if [ ! -d /opt/shell/shell_study/if_couse ]
then
mkdir /opt/shell/shell_study/if_couse
echo "创建成功"
fi
for 循环语句
语法一:
for i in `seq 1 9`
do
代码块
done
语法二:
for (( i=1,j=10;i<10;i++,j-- ))
do
代码块
done
例子
```powershell
# 实现倒计时
echo -n "倒计时:"
for i in `seq 9 -1 0`
do
echo -n -e "\b$i"
sleep 1
done
echo
echo "倒计时结束"
# 监控ping主机连接脚本
for(( ; ; ))
do
ping -c1 $1 &>/dev/null
if [ $? -eq 0 ]
then
echo -e "`date +"%F %H:%M:%S"`:$1 is \033[32m UP \033[0m"
else
echo -e "`date +"%F %H:%M:%S"`:$1 is \033[31m DOWN \033[0m"
fi
sleep 5
done
```
while 循环语句
语法:
while [ 无限循环条件 ] #循环条件为真时无限执行
do
代码块
done
until 循环语句
until [ 无限循环条件 ] #循环条件为假时无限执行
do
代码块
done
例子
打印10-20
a=1
while (( $a<10 ));do
echo "$a"
a=$(( a+1 ))
until (( $a<10));do
echo "$a"
a=$(( a+1 ))
if (( $a<20 ));then
break
fi
done
done
case 多条件语句
语法:
case 变量 in
条件1)
执行代码块1
;;
条件2)
执行代码块2
;;
...
esac
特殊参数
echo "脚本的名字:$0"
echo "脚本的参数是: $*"
echo "传参(形参和实参)的数量:$#"
echo "脚本执行进程号(PID):$$"
echo "最近一次执行命令是:$_"
echo "第2个参数是:$2"
函数
语法:
# 函数一
函数名 () {
代码块
}
# 函数二
function 函数名 {
代码块
}
# 函数调用
函数名
正则表达式
支持正则表达式的命令grep,sed,awk
特殊字符*
定位符 | 例子描述 | 匹配符 | 描述 | 限定符 | 描述 | ||
---|---|---|---|---|---|---|---|
^ | ^a 以a为开头进行搜索 | . | 任意字符 | * | a* a没有出现或多次出现 | ||
$ | a$ 以a为结尾进行搜索 | [] | [0-9]指定搜索0-9的范围 | ? | a? a只出现一次 | ||
\ | 转义字符 | + | a+ a必须出现一次或多次 | ||||
() | | (a|b)同时搜索a或b | {n,m} | a{n,m} a最少出现n次最多出现m次 | ||||
() | 分组 |
例子:
# 搜索座机电话号码
egrep '^[0-9]{3,4}-[0-9]{7,8}$' --color 文本名.txt
# 搜索腾讯网易邮箱
egrep '^([A-Za-z0-9[:punct:]]{6,10}|[0-9]{6,11})@(168|qq)\.com$' --color 文本名.txt
文件行编辑器
sed
语法:sed 选项 ‘命令’ 文件名
命令选项 | 描述 |
---|---|
-n | 只输出选中行 |
-e | 在一行中可多条件多操作 |
-f | 执行文件中的命令 |
-i | 修改原文件 |
-i.bak | 备份原文件再修改 |
#追加 a\ 插入 i\ 删除 d\
sed '/搜索字符串/a\hello world' 文件名
#改部分内容 s\
sed '/搜索字符串/s/hello world/hello/' 文件名 #替换第一处,/g 替换所有
#改整行内容 c\ 打印 p\
sed '/搜索字符串/c\hello world' 文件名
awk
语法:awk 选项 ‘BEGIN{}’
awk 选项 ‘代码块’ 数据源
awk 选项 ‘输出语句’ 数据源
选项 | 描述 | 例子 |
---|---|---|
-F | 指定分割符 | awk -F “:” ‘NR==1{print $1}’ etc/passwd 指定":"位分隔符 |
#打印
awk '{print $N}' 文件名 # 打印第N列,$0第一列,$NF最后一列
awk 'NR=N{print $N}' 文件名 # 打印第N列第N行,$0第一列,$NF最后一列
awk 'NR=N{print $N,$M,$U}' 文件名
awk 'END{print NR}' 文件名 # 打印文件多少行
awk 'END{print NF}' 文件名 # 打印文件多少列
awk 'END{print $0}' 文件名 # 打印文件最后一行内容
# 内存使用率
head /proc/meminfo | awk 'NR==1{t=$2}NR==2{f=$2;print (t-f)*100/t "%"}'
#BEGIN用法
awk 'BEGIN{FS=":";OFS="-"}$1=="root"{print $1,$3,$5}' /etc/passwd # 输出结果:root-0-root
# OFS:输出字段分隔符号
# FS:输入字段分隔符号
# RS:输入记录分隔符号
# ORS:输出记录分隔符
Shell 编写实例
监控一个主机状态
#监控主机状态
#方式一:
for ((i=1;i<4;i++));do
if ping -c1 $1 &>/dev/null;then
export ping_count"$i"=1
else
export ping_count"$i"=0
fi
#间隔时间
# 1s
sleep 1
done
#三次ping失败报警
if [ $ping_count1 -eq $ping_count2 ] && [ $ping_count2 -eq $ping_count3 ] &&[ $ping_count1 -eq 0 ];then
echo "$1 is dowm"
else
echo "$1 is up"
fi
unset ping_count1
unset ping_count2
unset ping_count3
#方式二:
#监控主机状态
IP="192.168.137"
for i in {150..170}
do
IP_UP=$IP.$i
for i in {1..3}
do
ping -c1 -w1 $IP_UP $>/dev/null
if [ $? -eq 0 ];then
echo $IP_UP 连接成功!
break
fi
echo $IP_UP 尝试"$i"次失败!
done
done
检测服务端口
#! /usr/bin/bash
# 监控一个服务端口
# 测试服务端口是否有响应 通过telnet协议
port_status () {
# 生成临时文件
temp_file=`mktemp prot_status.XXX`
# 1、判断依赖命令telnet是否存在
[ ! -x /usr/bin/telnet ]&&echo "telnet: not found command"&& exit 1
# 2、测试端口 $1 IP 和 $2 port
( telnet $1 $2 <<EOF
quit
EOF
) &>$temp_file
# 分析文件中的内容,半段结果
if egrep "\^]" $temp_file &>/dev/null;then
echo "$1 $2 is open"
else
echo "$1 $2 is close"
fi
rm -f $temp_file
查看内存和CUPtop10
memory_top10 () {
#1、收集任务管理器进程信息
temp_file=`mktemp memory.XXX`
top -b -n1 > $temp_file #-b显示所有进程
#2、按进程统计内存使用大小
tail -n +8 $temp_file | awk '{array[$NF]+=$10}END{for (i in array) print array[i],i}' | sort -k 1 -n -r|head -10
# tail -n +8 从文件第八行开始查看
rm -f $temp_file
}
cup_top10 () {
#1、收集任务管理器进程信息
temp_file=`mktemp cup.XXX`
top -b -n 1 > $temp_file #-b显示所有进程
#2、按进程统计cup使用大小
tail -n +8 $temp_file | awk '{array[$NF]+=$9}END{for (i in array) print array[i],i}' | sort -k 1 -n -r |head -10
rm -f $temp_file
}
echo "MEMORY"
memory_top10
echo "CUP"
cup_top10
安装nginx脚本(其他环境Java、Python、LAMP同理)
# 安装nginx
# 定义变量
nginx_pkg="nginx-1.18.0.tar.gz"
nginx_source_doc=`echo $nginx_pkg | cut -d "." -f 1-3`
nginx_install_doc="/usr/local/nginx"
nginx_user="nginx"
nginx_group="nginx"
# 检测
check () {
# 1、监测当前用户
if [ "$USER" != 'root' ];then
echo "need to be root so that"
exit 1
fi
}
# 2、检查wget命令
#if [ ! -x /usr/bin/wget ];then
# echo "not found command /usr/bin/wget"
# exit 1
#fi
# 2、检查wget命令
[ ! -x /usr/bin/wget ]&& echo "not found command /usr/bin/wget" && exit 1
# 安装依赖
install_pre () {
# 1、安装依赖
# 0 stdin(正确信息输入) 1 stdou(正确信息输出) 2 stderr(错误信
息)
if ! (yum -y install gcc pcre-devel zlib-devel elinks 1>/dev/null);then
echo "ERROR: yum install error"
exit 1
fi
#2、下载源码包
if wget http://nginx.org/download/$nginx_pkg &>/dev/null;then
tar xf $nginx_pkg
if [ ! -d $nginx_source_doc ];then
echo "ERROT: not found $nginx_source_doc"
exit 1
fi
else
echo "ERROR: download file $nginx_pkg fail"
exit 1
fi
}
# 安装nginx
install () {
#1、创建用管理户
useradd -r -s /sbin/nologin nginx
#2、安装nginx源码
cd $nginx_source_doc
echo "nginx configure..."
if ./configure --prefix=$nginx_install_doc --user=$nginx_user --group=$nginx_group 1>/dev/null;then
echo "nginx make..."
if make 1>/dev/null;then
echo "nginx install..."
if make install 1>/dev/null;then
echo "nginx install success"
else
echo "ERROR: nginx make install fail";exit 1
fi
else
echo "ERROR: nginx make fail";exit 1
fi
else
echo "ERROR: nginx cofigure fail";exit 1
fi
}
#测试
nginx_test () {
if $nginx_install_doc/sbin/nginx;then
echo "niginx start SUCCESS!"
# 测试链接
elinks http://localhost -dump
else
echo "nginx stop FAIL"
fi
}
##调用##
echo "this is nginx install script"
#交互
read -p "press Y install,press C cancel: " char
if [ $char == 'Y' ];then
check;install_pre;install;nginx_test
elif [ $char == 'C' ];then
exit 1
fi
#自动化
# check;install_pre;install;nginx_test
创建用户01-20
#创建用户01-20
adduser () {
pw_txt=`mktemp pw.XXXX`
echo -e "account\t\tpassword" > uesradd_result.txt
#1、创建用户
for i in `seq -s ' ' -w 1 20`
do
useradd user$i
done
#2、随即密码
cat /dev/urandom | strings -6 | egrep "^[A-Za-z0-9]{6}" | head -n 20 >$pw_txt
#3、设置密码
for i in `seq -s ' ' -w 1 20`;do
pw=`head -n $i $pw_txt | tail -1`
echo $pw | passwd --stdin user$i
echo -e "user$i\t\t$pw" >> useradd_result.txt
done
#4、输出
clear
echo "用户创建成功,密码文件是: useradd_result.txt"
cat useradd_result.txt
rm -rf $pw_txt
}
adduser