试题一
计算文档a.txt中每一行中出现的数字个数并且要计算一下整个文档中一共出现了几个数字。例如a.txt内容如下: 12aa*lkjskdj alskdflkskdjflkjj 我们脚本名字为 ncount.sh, 运行它时: bash ncount.sh a.txt 输出结果应该为: 2 0 sum:2
核心要点:
- while循环使用
- wc命令使用
#!/bin/bash
[ -f /etc/profile ] && . /etc/profile
sum_count=0
while read line
do
line_n=`echo line|sed 's/[^0-9]//g'|wc -L`
#echoline_n
sum_count=[sum_count+line_n]
done<1
echo "sum:$sum_count"
试题二
有两台Linux服务器A和B,假如A可以直接ssh到B,不用输入密码。A和B都有一个目录叫做/data/web/ 这下面有很多文件,
当然我们不知道具体有几层子目录,假若之前A和B上该目录下的文件都是一模一样的。
但现在不确定是否一致了。固需要我们写一个脚本实现这样的功能,检测A机器和B机器/data/web/目录下文件的异同,我们以A机器上的文件作为标准。
比如,假若B机器少了一个a.txt文件,那我们应该能够检测出来,或者B机器上的b.txt文件有过改动,我们也应该能够检测出来(B机器上多了文件不用考虑)。
核心要点:
- scp使用
- sed、awk使用
#!/bin/bash
[ -f /etc/profile ] && . /etc/profile
dir=/data/web
SSH_B=192.168.10.140
SSH_PORT=31235
function file_md5() {
find_dir=1
[ -f /tmp/md5.list ] && rm -rf /tmp/md5.list
findfind_dir -type f > /tmp/file.list
while read line
do
md5sum line >> /tmp/md5.list
donedir
scp -P SSH_PORT /tmp/md5.list root@SSH_B:/tmp/
[ -f ]
cat>/tmp/check_md5.sh<<EOF
#!/bin/bash
dir=/data/web
n=\`wc -l /tmp/md5.list|awk '{print \1}'\`
for i in \`seq 1 \$n\`
do
file_name=\`sed -n "\$i"p /tmp/md5.list|awk '{print \$2}'\`
md5=\`sed -n "\$i"p /tmp/md5.list|awk '{print \$1}'\`
if [ -f \$file_name ]; then
md5_b=\`md5sum \$file_name|awk '{print \$1}'\`
if [ "\$md5_b" != "\$md5" ]; then
echo "文件内容有修改"
fi
else
echo "文件:\$file_name不存在"
fi
done
EOF
scp -PSSH_PORT /tmp/check_md5.sh root@SSH_B:/tmp/
ssh -pSSH_PORT root@$SSH_B "/bin/bash /tmp/check_md5.sh"
试题三
一个脚本,检测你的网络流量,并记录到一个日志里。需要按照如下格式,并且一分钟统计一次(只需要统计外网网卡,假设网卡名字为eth0): 2017-08-04 01:11 eth0 input: 1000bps eth0 output : 200000bps
2017-08-04 01:12 eth0 input: 1000bps eth0 output : 200000bps 提示:使用sar -n DEV 1 59 这样可以统计一分钟的平均网卡流量,只需要最后面的平均值。另外,注意换算一下,1Byte=8bit
核心要点:
- sar命令
#!/bin/bash
# yum install sysstat -y
[ -f /etc/profile ] && . /etc/profile
function network_check() {
interval=1
flag_count=2
network_eth=3
d_time=`date +'%Y-%m-%d %H:%M:%S'`
rx=`sar -n DEVinterval flag_count|grepnetwork_eth|egrep -v "^[0-9]"|awk '{print 5}'`
tx=`sar -n DEVinterval flag_count|grepnetwork_eth|egrep -v "^[0-9]"|awk '{print 6}'`
rx_kbps=`echo "rx * 8"|bc`
tx_kbps=`echo "tx * 8"|bc`
echo "d_time network_eth input:{rx_kbps}kbps output:${tx_kbps}kbps"
}
network_check 1 5 ens192
试题四
一台机器负载高,top查看有很多sh的进程,然后top -c查看可以看到对应的进程命令是sh -c /bin/clearnen.sh 。
经分析后发现是因为该脚本执行时间太长,导致后续执行时,上次的脚本还未执行结束。写一个脚本批量杀死所有sh的进程。
#!/bin/bash
for pid in `ps aux |grep clearnen.sh |awk '{print 2}'`
do echopid
kill -9 $pid
done
试题五
写一个脚本判断你的Linux服务器里是否开启web服务?(监听80端口)如果开启了,请判断出跑的是什么服务,是httpd呢还是nginx又或者是其他的什么?
#!/bin/bash
n=`netstat -lntp |grep ':80 '|wc -l`
if [ n -eq 0 ]
then
echo "It not listen port 80"
else
ser=`netstat -lntp |grep ':80 '|awk -F '/' '{printNF}'|sed 's/ //g'`
echo "It is listenning port 80, and the service is $ser."
fi
试题六
假设,当前MySQL服务的root密码为123456,写脚本检测MySQL服务是否正常(比如,可以正常进入mysql执行show processlist),
并检测一下当前的MySQL服务是主还是从,如果是从,请判断它的主从服务是否异常。如果是主,则不需要做什么。
核心要点:
- 通过连接状态查看主从复制
[root@slave_DB ~]# cat /root/scripts/mysql_status.sh
#!/bin/bash
#
#监控mysql复制,20180123
mysql_socket=/usr/local/mysql/mysql.sock
user=root
passwd=123456
Mysqlsql="mysql -u{user} -p{passwd} -S mysql_socket"
mysql_status() {
SQLresult=`/usr/local/mysql/bin/mysql --defaults-extra-file=/usr/local/mysql/my.cnf -e "show slave status\G"|egrep "\<Slave_IO_Running\>|\<Slave_SQL_Running\>" |awk '{print2}'`
REVELT=?
if [REVELT -ne 0 ];then
echo 0
return 8
fi
SQLarray=(SQLresult)
if [ "{SQLarray[0]}" == "Yes" -a "{SQLarray[1]}" == "Yes" ];then
echo 1
else
echo 0
fi
}
let result=`mysql_status`
if [result -eq 1 ]; then
echo "主从连接正常"
else
echo "主从连接异常"
fi
试题七
写一个支持选项的增加或删除用户的shell脚本,具体要求如下:
1.只支持三个选项:’–del’,’–add’,’–help’,输入其他选项报错。
2.使用’–add’时,需要验证用户名是否存在,存在则反馈存在,且不添加。 不存在则创建该用户,需要设置与该用户名相同的密码。
3.使用’–del’时,需要验证用户名是否存在,存在则删除用户及其家目录。不存在则反馈该用户不存在。
4.–help选项反馈出使用方法。
5.能用echo $?检测脚本执行情况,成功删除或添加用户为0,不成功为非0正整数。
6.能以英文逗号分割,一次性添加或者删除多个用户。例如 adddel.sh –add user1,user2,user3
核心要点:
- useradd使用
- 命令执行状态码判断
#!/bin/bash
[ -f /etc/profile ] && . /etc/profile
function user_add() {
users=1
n=`echousers|awk -F ',' '{print NF}'`
for i in `seq 1 n`
do
new_user=`echousers|awk -F ',' -v j=i '{printj}'`
id new_user &>/dev/null
if [? -eq 0 ]; then
echo "用户:new_user已存在"
else
useraddnew_user
echo "new_user"|passwd --stdinnew_user &>/dev/null
if [ ? -ne 0 ]; then
echo "用户:new_user添加失败"
else
echo "用户:new_user添加成功"
fi fi
done
}
function user_del() {
users=1
n=`echo users|awk -F ',' '{print NF}'`
for i in `seq 1n`
do
new_user=`echo users|awk -F ',' -v j=i '{print j}'`
idnew_user &>/dev/null
if [ ? -eq 0 ]; then
userdel -rnew_user
echo "用户:new_user删除成功"
else echo "用户:new_user不存在"
fi
done
}
case 1 in
--add)
user_add2
;;
--del)
user_del $2
;;
--help)
echo "USAG:{--add|--del}"
;;
*)
echo "USAG:{--add|--del|--help}"
;;
esac
试题八
写一个脚本: 计算100以内所有能被3整除的正整数的和
核心要点:
- 取余运算
#!/bin/bash
[ -f /etc/profile ] && . /etc/profile
sum_count=0
for i in `seq 1 100`
do
result=`echo "i%3"|bc`
if [result -eq 0 ]; then
sum_count=[sum_count+i]
fi
done
echo "sum:sum_count"
试题九
使用传参的方法写个脚本,实现加减乘除的功能。 例如: sh a.sh 1 2,这样会分别计算加、减、乘、除的结果。
要求:
- 脚本需判断提供的两个数字必须为整数
- 当做减法或者除法时,需要判断哪个数字大,减法时需要用大的数字减小的数字,除法时需要用大的数字除以小的数字,并且结果需要保留两个小数点。
核心要点:
- bc命令使用
#!/bin/bash
[ -f /etc/profile ] && . /etc/profile
if [ # -ne 2 ]; then
echo "输入两个整数参数"
exit 4
fi
s1=`echo1|sed 's/[0-9]//g'`
if [ -n "s1" ]; then
echo "参数请输入整数"
exit 3
fi
s2=`echo2|sed 's/[0-9]//g'`
if [ -n "s2" ]; then
echo "参数请输入整数"
exit 4
fi
function addition() {
sum_count=`echo "1+2"|bc`
echosum_count
}
function subtraction() {
if [ 1 -ge2 ]; then
max_flag=1
min_flag=2
else
max_flag=2
min_flag=1
fi
flag=`echo "max_flag-min_flag"|bc`
echo flag
}
function multip() {
if [1 -ge 2 ]; then
max_flag=1
min_flag=2
else
max_flag=2
min_flag=1
fi
flag=`echo "{max_flag}*{min_flag}"|bc`
echoflag
}
function division() {
if [ 1 -ge2 ]; then
max_flag=1
min_flag=2
else
max_flag=2
min_flag=1
fi
flag=`echo "scale=2;{max_flag}/{min_flag}"|bc`
echo flag
}
echo "加法运算"
result=`addition*`
echo result
echo "---"
echo "减法运算"
result=`subtraction*`
echo result
echo "---"
echo "乘法运算"
result=`multip*`
echo result
echo "---"
echo "除法运算"
result=`division*`
echo $result
试题十
写一个脚本,执行后,打印一行提示“Please input a number:”,要求用户输入数值,然后打印出该数值,然后再次要求用户输入数值。直到用户输入”end”停止。
核心要点:
- read使用
#!/bin/bash
function read_line() {
read -p "Please input a number:" str
if [ "str" == "end" ]; then
return 1
fi
new_str=`echostr|sed 's/[0-9]//g'`
if [ -n "new_str" ]; then
echo '参数请输入整数'
return 2
fi
echostr
return 0
}
flag=true
echo "输入end退出打印!"
while flag
do
s=`read_line`
if [? -eq 1 ]; then
echo "exit..."
flag=false
fi
echo $s
done
#备注:写的不好
留言