试题一
请按照这样的日期格式(xxxx-xx-xx)每日生成一个文件, 例如生成的文件名为2017-12-20.log, 并且把磁盘的使用情况写到到这个文件中, 不用考虑cron,仅仅写脚本即可
核心要点:
- date用法
- 日志规范
#!/bin/bash
d=`date +%F`
d_time=`date +'%Y-%m-%d %H:%M:%S'`
dir=/data/logs/disklog
if [ ! -d $dir ]; then
mkdir -p $dir
fi
function disk_find() {
shell_cmd=$@
[ ! -f $dir/$d.log ] && touch $dir/$d.log
echo "$d_time INFO 日志检查" >> $dir/$d.log
$shell_cmd 1>>$dir/$d.log
if [ $? -ne 0 ]; then
echo '命令或参数不正确!'>>$dir/$d.log
fi
}
disk_find $*
试题二
有日志1.log,部分内容如下
112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com “/seccode.php?update=0.5593110133088248″ 200″http://formula-x.haotui.com/registerbbs.php” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)”
61.147.76.51 – [25/Sep/2013:16:08:31 +0800]xyzdiy.5d6d.com “/attachment.php?aid=4554&k=9ce51e2c376bc861603c7689d97c04a1&t=1334564048&fid=9&sid=zgohwYoLZq2qPW233ZIRsJiUeu22XqE8f49jY9mouRSoE71″ 301″http://xyzdiy.5d6d.com/thread-1435-1-23.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)”
统计出每个IP访问量有多少
核心要点:
- awk用法
- sort用法
- uniq用法
awk '{print $1}' 1.log |sort |uniq -c
试题三
写一个脚本计算一下linux系统所有进程占用内存大小的和。
核心要点:
- 内存使用率命令ps aux
- awk用法
- 循环用法
方法一
ps aux|awk '{print $6}'|grep -v 'TIME COMMAND'|while read line; do a=$[$a+$line];echo $a; done;
方法二
#!/bin/bash
sum=0
for i in `ps aux|awk '{print $6}'|grep -v 'TIME COMMAND'`
do
sum=$[$sum+$i]
done
echo $sum
试题四
设计一个脚本,监控远程的一台机器(假设ip为192.168.10.180)的存活状态,当发现宕机时发一封邮件给你自己。
核心要点:
- 通过nc命令监测远程端口3389或者22(本例ssh端口:31235)
- 此处省略邮件发送直接以echo形式输出
#!/bin/bash
# yum install -y nc
IP_HOST=192.168.10.180
PORT=31235
function host_check() {
host=$1
port=$2
nc -v -w 1 $host -z $port &>/dev/null
if [ $? -eq 0 ]; then
echo '服务器状态监测正常'
else
echo '服务器状态监测异常'
fi
}
host_check $IP_HOST $PORT
试题五
找到/123目录下所有后缀名为.txt的文件
- 1.批量修改.txt为.txt.bak
- 2.把所有.bak文件打包压缩为123.tar.gz
- 3.批量还原文件的名字,即把增加的.bak再删除
核心要点:
- find命令使用
- tar命令使用
- rm命令使用
#!/bin/bash
dir_path='/123'
[ -d $dir_path ] && cd $dir_path || exit 8
find ./ -name "*.txt" -type f|while read file
do
mv $file $file.bak
echo $file.bak
done > /tmp/file.txt
if [ -s /tmp/file.txt ]; then
tar -czvf 123.tar.gz `cat /tmp/file.txt`
for i in `cat /tmp/file.txt`
do
rm -rf $i
done
else
echo '无打包文件'
fi
试题六
写一个脚本,判断本机的80端口(假如服务为httpd)是否开启着,如果开启着什么都不做,如果发现端口不存在,那么重启一下httpd服务, 并发邮件通知你自己。脚本写好后,可以每一分钟执行一次,也可以写一个死循环的脚本,30s检测一次。
核心要点:
- nc命令监测端口
- 重启httpd服务
#!/bin/bash
# yum install -y nc
HOST_IP=192.168.10.180
PORT=80
function server_tcp_check() {
host_ip=$1
port=$2
d_time=`date +'%Y-%m-%d %H:%M:%S'`
nc -v -w 1 $host_ip -z $port &>/dev/null
result=$?
if [ $result -eq 0 ]; then
echo "$d_time [INFO] HOST:$host_ip:$port 检查正常"
else
echo "$d_time [ERROR] HOST:$host_ip:$port 检查异常,即将重启端口:$port"
sudo systemctl restart httpd
fi
sleep 5
}
while true
do
echo '服务端口状态检查...'
server_tcp_check $HOST_IP $PORT
done
试题七
设计一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝一份,本地保存一周的数据,远程保存一个月。
假定,我们知道mysql root账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql, 远程服务器ip为192.168.123.30, 远程提供了一个rsync服务,备份的地址是 192.168.123.30::backup . 写完脚本后,需要加入到cron中,每天凌晨3点执行。
核心要点:
- rsync用法
- mysql备份用法
#!/bin/bash
. /etc/profile
#数据库用户名
##GRANT SELECT, RELOAD, SUPER, LOCK TABLES ON *.* TO 'mysqldumper'@'localhost' identified by 're8Z3db57dltINJdWF5e&2fMu';
##flush privileges ;
dbuser='mysqldumper'
#数据库用密码
dbpasswd='re8Z3db57dltINJdWF5e&2fMu'
#备份时间
backtime=`date '+%Y%m%d%H%M%S'`
t_time=`date '+%Y-%m-%d %H:%M:%S'`
#日志备份路径
logpath='/data/mysqlbakup'
#数据备份路径
datapath='/data/mysqlbakup'
if [ ! -d ${datapath} ];then
mkdir ${datapath} -p
fi
#日志记录头部
echo "备份时间为${t_time},备份数据库表 ${dbname} 开始" >> ${logpath}/log.log
#获取数据库名
#dbname=`mysql -u${dbuser} -p${dbpasswd} -e "show databases;" |egrep -v "Database|sys|information_schema|mysql|performance_schema"`
dbname='discuz'
#正式备份数据库
for db in $dbname; do
mysqldump -u${dbuser} -p${dbpasswd} -F -B $db --master-data={1,2} --single-transaction |gzip> ${logpath}/${db}${backtime}.sql.gz 2>> ${logpath}/mysqllog.log
#备份成功以下操作
if [ "$?" == 0 ];then
cd $datapath
#删除七天前备份,也就是只保存7天内的备份
find $datapath -name "*.gz" -type f -mtime +7 -exec rm -rf {} \; > /dev/null 2>&1
echo "${t_time} 数据库 ${db} 备份成功!!" >> ${logpath}/mysqllog.log
else
#备份失败则进行以下操作
echo "${t_time} 数据库 ${db} 备份失败!!" >> ${logpath}/mysqllog.log
fi
done
rsync -avzP $datapath rsync_backup@192.168.10.140::backup/ --password-file=/etc/rsyncd.pas
#备注:这里想用rsync实现远端删除30天前的文件还是有点难度,可以在远端单独写个find操作
试题八
服务器上跑的是LNMP环境,近期总是有502现象。502为网站访问的状态码,200正常,502错误是nginx最为普遍的错误状态码。
由于502只是暂时的,并且只要一重启php-fpm服务则502消失,但不重启的话,则会一直持续很长时间。
所以有必要写一个监控脚本,监控访问日志的状态码,一旦发生502,则自动重启一下php-fpm。
核心要点:
- 读取日志
- 判断异常处理(shell目前没有发现好的方法精准读取每一行,只能泛匹配)
#!/bin/bash
[ -f /etc/profile ] && . /etc/profile
ACCESS_LOG=/var/log/httpd/access_log
ERROR_CODE=403
function check_log() {
check_log=$1
code=$2
d_time=`date +'%Y-%m-%d %H:%M:%S'`
tail -300 $check_log|awk '{print $9}'|grep $code &>/dev/null
if [ $? -eq 0 ]; then
echo "$d_time 日志检查异常,服务即将重启"
sudo systemctl restart httpd.service
else
echo "$d_time 日志检查正常"
fi
sleep 5
}
while true
do
check_log $ACCESS_LOG $ERROR_CODE
done
#备注:本机没搞LNMP,难得去配置环境,大体就是这种模式实现,只是tail -300 还是显得极lower,通过python可以进行整行读取
试题九
把一个文本文档的前5行中包含字母的行删除掉,同时把6到10行中的全部字母删除掉。
核心要点:
- sed命令使用
sed -n '1,5'p get-pip.py |sed '/[A-Za-z]/d'
sed -n '6,10'p get-pip.py |sed 's/[A-Za-z]//g'
试题十
shell打印下面这句话中字母数小于6的单词。 Bash also interprets a number of multi-character options.
核心要点:
- awk用法
- wc用法
#!/bin/bash
c="Bash also interprets a number of multi-character options."
n=`echo $c|awk -F '[ +-.]' '{print NF}'`
for ((i=0;i<$n;i++))
do
l=`echo $c|awk -F '[ +-.]' -v j=$i '{print $j}'|wc -L`
if [ $l -lt 6 ]; then
echo `echo $c|awk -F '[ +-.]' -v j=$i '{print $j}'`
fi
done
留言