企业面试题之shell脚本¶
1. 批量生成随机字符文件名¶
使用for循环在/oldboy目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串oldboy。
思路分析
核心是:创建10个随机小写字母
#7种方法
1.echo $RANDOM
2.openssl rand -base64 100
3.date +%s%N
4.head /dev/urandom|cksum
5.uuidgen
6.cat /proc/sys/kernel/random/uuid
7.mkpasswd(yum install expect -y)
mkpasswd参数
-l 长度
-d 数字
-c 小写字母
-C 大写字母
-s 特殊字符
例1:
mkpasswd -l 20 -d 10 -C 5 -c 3 -s 2
[root@cp ~]# mkpasswd -l 20 -d 10 -C 5 -c 3 -s 2
810Q,hl46#B76C46b1CV
例2:
echo OLDBOY$RANDOM|md5sum|tr "0-9" "a-z"|cut -c 2-11
[root@cp ~]# echo OLDBOY$RANDOM|md5sum|tr "0-9" "a-z"|cut -c 2-11
gicdfhjaag
脚本
#!/bin/bash
path=/oldboy
[ -d $path ] || mkdir $path
for n in {1..10}
do
random=`echo "OLDBOY$RANDOM"|md5sum|tr "0-9" "m-z"|cut -c 2-11`
touch $path/${random}_oldboy.html
done
2. 批量改名¶
将面试题1种的oldboy改为oldgirl(最好用for循环实现),并且将扩展名html改成大写
思路分析
1.要改所有,先缩小改一个
2.修改所有,用for循环
#!/bin/bash
for file in `ls /oldboy/*.html`
do
mv $file `echo ${file/oldboy.html/oldgirl.HTML}`
done
3. 批量创建特殊要求用户¶
批量创建10个系统账号oldboy01-10并设置密码(密码要求字符数字等混合)
此题重点:必须要,经常考,要给出2种以上方法
思路分析
1) 01..10产生方法
echo {01..10}
seq -w 10
2) 随机数
openssl rand -base64 100
3) 创建用户
useradd oldboy01
4) 设置密码
echo 密码|passwd --stdin
方法2:
chpasswd oldboy01:passwd
脚本
#!/bin/bash
for n in {01..10}
do
pass=`openssl rand -base64 10`
useradd oldboy$n
echo $pass|passwd --stdin oldboy$n
echo -e "oldboy$n\t$pass" >>/tmp/user.list
done
方法2
#!/bin/bash
for n in `seq -w 1 10`
do
pass=`openssl rand -base64 10`
useradd oldboy$n
echo "oldboy$n:$pass" >> /tmp/chpasswd.log
done
chpasswd < /tmp/chpasswd.log
改进:加上root用户验证
#!/bin/bash
. /etc/init.d/functions
if [ $UID -ne 0 ];then
echo "必须使用root用户执行本脚本!!!"
exit 1
fi
for n in {20..30}
do
pass=`openssl rand -base64 10`
if [ `grep -w "oldboy$n" /etc/passwd|wc -l` -eq 0 ];then
useradd oldboy$n &>/dev/null
echo $pass|passwd --stdin oldboy$n &>/dev/null && \
echo -e "oldboy$n\t$pass" >>/tmp/user.list && \
action "oldboy$n is ok." /bin/true
else
action "oldboy$n is fail." /bin/false
fi
done
3.1 批量创建10个用户stu01-stu10,设置随机8为密码,要求只能用linux命令及管道实现,不能用循环¶
方法1:(以下方法都未验证。。。)
echo stu{01..10}|tr " " "\n" |sed -r 's#(.*)#useradd \1;
pass=$((RANDOM+10000000));echo "$pass|passwd --stdin \1;echo -e "\1\t`echo "$pass"`">>/tmp/lodboy.log#g'|bash
拆解如下
useradd stu01;
pass=$((RANDOM+10000000));
echo "$pass"|passwd --stdin stu01;
echo -e "stu01 `echo "$pass"`">>/tmp/oldboy.log
方法2
echo stu{11..12}|xargs -n1 useradd;echo stu{11..12}:`cat /dev/urandom|tr -dc 0-9|fold -w8|head -1`|xargs -n1 |tee -a pass.txt|chpasswd
方法3
echo stu{21..30}|tr "" "\n"|sed -e 's/^/useradd /' -e 's/\(stu[0-9]\{2\}\)$/\1 \&\& echo "\1:`echo $[$RANDOM**3]|cut -c1-8`"|tee -a userinfo.txt|cut -d: -f2|passwd --stdin \1/' |bash
方法4
echo stu{01..10}|tr ' ' '\n'|sed -rn 's@^(.*)$@useradd\1;echo $RANDOM |md5sum|cut -c 1-8 >/data/\1;cut /data/\1|passwd --stdin \1@gp'|bash
4. 扫描网络内的存活主机¶
写一个脚本,判断10.0.0.0/24网络里,当前在线的IP有哪些
思路分析
1.如何判断主机存活
ping -c 2 -i 1 -w 3 10.0.0.7
nmap -sP 10.0.0.0/24
root@4c16g:/shell-scripts# nmap -sP 10.0.8.0
Starting Nmap 7.80 ( https://nmap.org ) at 2022-01-05 15:39 CST
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 3.10 seconds
root@4c16g:/shell-scripts# nmap -sP 10.0.8.1
Starting Nmap 7.80 ( https://nmap.org ) at 2022-01-05 15:39 CST
Nmap scan report for 10.0.8.1
Host is up (0.012s latency).
Nmap done: 1 IP address (1 host up) scanned in 0.15 seconds
脚本
for n in {1..254}
do
if `ping -c 1 -w 3 10.0.0.$n &>/dev/null`
then
echo "10.0.0.$n is up."
else
echo "10.0.0.$n is down."
fi
done
以上速度比较慢,可以批量ping,提高速度
for n in {1..254}
do
{
if `ping -c 1 -w 3 10.0.0.$n &>/dev/null`
then
echo "10.0.0.$n is up."
else
ehco "10.0.0.$n is down."
fi
} &
done
5. mysql数据库分库备份¶
思路分析:
常规方法
mysqldump -B oldboy oldgirl test | gzip >bak.sql.gz
分库备份
mysqldump -B oldboy | gzip >bak.sql.gz
mysqldump -B oldgirl | gzip >bak.sql.gz
mysqldump -B test | gzip >bak.sql.gz
脚本
#!/bin/bash
[ -d /backup ] || mkdir /backup -p
for dname in `mysql -uroot -p123456 -e "show databases;" 2>/dev/null |grep -v _schema|sed 1d`
do
mysqldump -uroot -p123456 -B $dbname|gzip >/backup/${dbname}.sql.gz
done
优化
#!/bin/bash
mysql="mysql -uroot -p123456"
mysqldump="mysqldump -uroot -p123456"
path="/backup"
[ -d $path ] ||mkdir $path -p
for dbname in `$mysql -e "show databases;" 2>/dev/null|grep -v _schema|sed 1d`
do
$mysqldump -B $dbname|gzip >$path/${dbname}_$(date +%F).sql.gz
done
6. mysql数据库分库分表备份¶
思路分析
mysqldump oldboy test test1 |gzip >bak.sql.gz
1.oldboy 数据库名
2.test、test1 表名
方法2
mysqldump -B oldboy |gzip >bak.sql.gz
mysqldump oldboy test1
mysqldump oldboy test2
mysqldump oldboy test3
脚本
#!/bin/bash
path=/backup
mysql="mysql -uroot -p123456"
mysqldump="mysqldump -uroot -p123456"
[ -d $path ] || mkdir $path -p
for dbname in `$mysql -e "show databases;" 2>/dev/null |grep -v _schema|sed 1d`
do
for tname in `$mysql -e "show tables from $dbname;" 2>/dev/nulll |sed 1d`
do
$mysqldump $dbname $tname |gzip >$path/${dbname}_${tname}.sql.gz 2>/dev/null
done
done
也可以修改配置文件,加入如下参数,防止在脚本中加入密码
vim /etc/my.cnf
[client]
user=root
password=123456
则,脚本中可以省略密码
#!/bin/bash
path=/backup
[ -d $path ] || mkdir $path -p
for dbname in `mysql -e "show databases;" 2>/dev/null |grep -v _schema|sed 1d`
do
for tname in `mysql -e "show tables from $dbname;" 2>/dev/nulll |sed 1d`
do
mysqldump $dbname $tname |gzip >$path/${dbname}_${tname}.sql.gz 2>/dev/null
done
done
改造,跳过报错数据库
#!/bin/bash
path=/backup
[ -d $path ] || mkdir $path -p
for dbname in `mysql -e "show databases;" 2>/dev/null |grep -v _schema|sed 1d`
do
for tname in `mysql -e "show tables from $dbname;" 2>/dev/nulll |sed 1d`
do
if [ "$dbname" = "mysql" ];then
mysqldump --skip-lock-tables $dbname $tname |gzip >$path/${dbname}_${tname}.sql.gz 2>/dev/null
else
mysqldump $dbname $tname |gzip >$path/${dbname}_${tname}.sql.gz 2>/dev/null
fi
done
done
7. ssh免密钥批量分发文件专业脚本¶
有3台机器(m01,backup,nfs01),采用ssh免密钥实现从m01到其他两台机器无密码登录后,请写脚本实现从m01批量分发任意文件到其他两台机器的任意目录下
思路分析
1.生成密钥
ssh-keygen
2.分发密钥
ssh-copy-id -i id_rsa.pub 10.0.0.8
ssh-copy-id -i id_rsa.pub 10.0.0.41
3.测试
ssh 10.0.0.8 free -m
ssh 10.0.0.41 free -m
测试脚本
vim ssh_test.sh
#!/bin/bash
if [ $# -ne 1 ];then
echo "usage: $0 cmd"
exit 1
fi
for n in 8 41
do
echo "-----------10.0.0.$n--------------"
ssh 10.0.0.$n $1
done
bash ssh_test.sh "df -h"
分发文件脚本
#!/bin/bash
for n in 8 41
do
echo "-----------10.0.0.$n---------"
scp -rp /oldboy 10.0.0.$n:/opt
done
改造
#!/bin/bash
if [ $# -ne 2 ];then
echo "usage:$0 localdir remotedir"
exit 1
fi
for n in 8 41
do
echo "-----10.0.0.$n--------"
scp -rp $1 10.0.0.$n:$2
done
优化
#!/bin/bash
. /etc/init.d/functions
if [ $# -ne 2 ];then
echo "usage:$0 localdir remotedir"
exit 1
fi
for n in 8 41 42 43
do
scp -rp $1 10.0.0.$n:$2 &>/dev/null
if [ $? -eq 0 ];then
action "10.0.0.$n is ok" /bin/true
else
action "10.0.0.$n is fail" /bin/false
fi
done
8. 破解random随机数¶
已知下面的字符串,请破解对应的使用MD5sum处理前的数字
21029299
00205d1c
a3da1677
1f6d12dd
890684b
思路分析
grep "1f6d12dd" md5.log |wc -l
脚本
array=(
21029299
00205d1c
a3da1677
1f6d12dd
890684b
)
Funmd5(){
for n in {0..32767}
do
echo -e "$n\t`echo $n|md5sum`" >>/tmp/md5sum.log
done
}
FunJudge(){
for n in ${array[*]}
do
find=`grep $n /tmp/md5sum.log`
if [ `echo $find|wc -l` -eq 1 ];then
echo $find
fi
done
}
main(){
Funmd5
FunJudge
}
main
方法2
array=(
21029299
00205d1c
a3da1677
1f6d12dd
890684b
)
Funmd5(){
for n in {0..32767}
do
echo -e "$n\t`echo $n|md5sum`" >>/tmp/md5sum.log &
done
}
FunJudge(){
char=`echo ${array[*]} |tr " " "|"`
egrep "$char" /tmp/md5sum1.log
}
main(){
Funmd5
FunJudge
}
main
9. 批量检查多个网站地址是否正确¶
要求:
1.使用shell数组方法实现,检测策略尽量模拟用户访问
2.每10秒做一次所有的检测,无法访问的输出报警
3.待检测网址如下
#!/bin/bash
. /etc/init.d/functions
URL=(
http://blog.oldboyedu.com
http://blog.etiantian.org
http://www.luffycity.com
http://10.0.0.7
)
CheckUrl(){
wget -t 2 -T 5 -o /dev/null -q $1
if [ $? -eq 0 ];then
action "$1 is ok" /bin/true
lese
action "$1 is fail" /bin/false
fi
}
DealUrl(){
for((i=0;i<${#URL[*]};i++))
do
CheckUrl ${URL[i]}
done
}
main(){
while true
do
DealUrl
sleep 10
echo "--------------------------------"
done
}
main
方法2
vim url.log
http://blog.oldboyedu.com
http://blog.etiantian.org
http://www.luffycity.com
http://10.0.0.7
#!/bin/bash
. /etc/init.d/functions
CheckUrl(){
wget -t 2 -T 5 -o /dev/null -q $1
if [ $? -eq 0 ];then
action "$1 is ok" /bin/true
lese
action "$1 is fail" /bin/false
fi
}
DealUrl(){
while read line
do
CheckUrl $line
done <./url.log
}
main(){
while true
do
DealUrl
sleep 10
echo "--------------------------------"
done
}
main
10. 解决DOS攻击¶
请根据web日志或者网络连接数,监控当某个IP并发链接数或者短时间内PV达到100,即调用防火墙命令封掉对应的IP。
防火墙命令为:iptables -I INPUT -s IP -j DROP
思路分析
1.封IP命令
iptables -I INPUT -s IP -j DROP
2.web日志活网络链接数
netstat -an|grep -i est
3.判断pv或者链接数大于100,取出IP封掉
脚本
#!/bin/bash
awk '{S[$1]++}END{for(key in S) print S[key],key}' access.log |sort -rn |head >/tmp/ip.log
while read line
do
if [ `echo $line |awk '{print $1}'` -gt 100 ];then
iptables -I INPUT -s `echo $line|awk '{print $2}'` -j DROP && \
echo "echo $line |awk '{print $2}'" >>/tmp/drop.log
else
echo "echo $line|awk '{print $2}'" >>/tmp/accept.log
fi
done </tmp/ip.log
改造
#!/bin/bash
awk '{S[$1]++}END{for(key in S) print S[key],key}' access.log |sort -rn |head >/tmp/ip.log
while read line
do
ip=`echo $line |awk '{print $2}'`
count=`echo $line |awk '{print $1}'`
if [ $count -gt 35 -a `grep "$ip" /tmp/drop.log|wc -l` -lt 1 ];then
iptables -I INPUT -s $ip -j DROP && \
echo "$ip" >>/tmp/drop.log
else
echo "$ip" >>/tmp/accept.log
fi
done </tmp/ip.log
方法2
#!/bin/bash
awk '/ESTAB/{print $0}' netstat.log |awk -F "[ :]+" '{print $(NF-3)}' |sort |uniq -c |sort -rn |head >/tmp/ip.log
while read line
do
ip=`echo $line|awk '{print $2}'`
count=`echo $line|awk '{print $1}'`
if [ $count -gt 100 -a `grep "$ip" /tmp/drop.log |wc -l` -lt 1 ];then
iptables -I INPUT -s $ip -j DROP
echo $ip >>/tmp/drop.log
else
echo $ip >>/tmp/accept.log
fi
done</tmp/ip.log
11.开发MySQL服务启停脚本(与rsync启停脚本类似)¶
lsof -i :3306
思路分析
1.实现效果
/et/init.d/mysqld {start|stop|restart}
2.启动
mysqld_safe --user=mysql &
3.停止
killall,pkill
kill pid
脚本
#!/bin/bash
lockfile=/var/lock/subsys/mysqld
. /etc/init.d/functions
mysqld_pid_file_path="/appliacation/mysql/data/`uname -n`.pid"
mysqld_safe=/application/mysql/bin/mysqld_safe
start(){
/bin/sh $mysqld_safe --datadir=/application/mysql/data --pid-file=$mysqld_pid_file_path &>/dev/null &
retval=$?
if [ $retval -eq 0 ];then
action "mysql startup ok" /bin/true
touch $lockfile
return $retval
else
action "mysql startup fail" /bin/false
return $retval
fi
}
stop(){
if test -s "$mysqld_pid_file_path"
then
mysqld_pid=`cat $mysqld_pid_file_path`
if (kill -0 $mysqld_pid &>/dev/null)
then
kill $mysqld_pid
retval=$?
if [ $retval -eq 0 ];then
action "mysql stop ok" /bin/true
rm $lockfile
return $retval
else
action "mysql stop fail" /bin/false
return $retval
fi
else
echo "mysqld process is not exist."
return 2
fi
else
echo "$mysqld_pid_file_path is not exist,or mysqld does not startup."
fi
}
case "$1" in
start)
start
retval=$?
;;
stop)
stop
retval=$?
;;
restart)
stop
sleep2
start
retval=$?
;;
*)
echo "usage: $0 {start|stop|restart}"
exit 1
esac
exit $retval
12. 单词及字母去重排序(排序去重面试非常常见!!!)¶
1.按单词出现频率降序排序
2.按字母出现频率降序排序
the squid project provides a number of resources to assist users design,implement and support squid installations. Please browse the documentation and support sections for more infomation,by oldboy training.
思路分析
1.tr " ," "\n" <12.log |sort |uniq -c |sort -rn
2.tr " ," "\n" <12.log |awk '{S[$1]++}END{for(k in S) print S[k],k}'|sort -rn
3.xargs -n1 <12.log
[root@k8s-master tmp]# tr " ," "\n" <12.log |sort |uniq -c |sort -rn 2 the
2 support
2 squid
2 and
1 users
1 training.
1 to
1 sections
1 resources
1 provides
1 project
1 Please
1 oldboy
1 of
1 number
1 more
1 installations.
1 infomation
1 implement
1 for
1 documentation
1 design
1 by
1 browse
1 assist
1 a
[root@k8s-master tmp]# tr " ," "\n" <12.log |awk '{S[$1]++}END{for(k in S) print S[k],k}'|sort -rn
2 the
2 support
2 squid
2 and
1 users
1 training.
1 to
1 sections
1 resources
1 provides
1 project
1 Please
1 oldboy
1 of
1 number
1 more
1 installations.
1 infomation
1 implement
1 for
1 documentation
1 design
1 by
1 browse
1 assist
1 a
[root@k8s-master tmp]# xargs -n1 <12.log|sort|uniq -c |sort -rn
2 the
2 support
2 squid
2 and
1 users
1 training.
1 to
1 sections
1 resources
1 provides
1 project
1 Please
1 oldboy
1 of
1 number
1 more
1 installations.
1 infomation,by
1 for
1 documentation
1 design,implement
1 browse
1 assist
1 a
sed 's# ##g' 12.log
[root@k8s-master tmp]# sed 's# ##g' 12.log
thesquidprojectprovidesanumberofresourcestoassistusersdesign,implementandsupportsquidinstallations.Pleasebrowsethedocumentationandsupportsectionsformoreinfomation,byoldboytraining.
grep -o "." 12.log|sort|uniq -c |sort -rn
[root@k8s-master tmp]# grep -o "." 12.log|sort|uniq -c |sort -rn
27
19 s
18 o
17 e
15 t
14 n
14 i
12 r
10 a
8 u
8 d
7 p
6 m
5 l
4 c
4 b
3 f
2 y
2 q
2 h
2 g
2 .
2 ,
1 w
1 v
1 P
1 j
grep -o "[^ ]" 12.log |sort | uniq -c |sort -rn
[root@k8s-master tmp]# grep -o "[^ ]" 12.log |sort | uniq -c |sort -rn
19 s
18 o
17 e
15 t
14 n
14 i
12 r
10 a
8 u
8 d
7 p
6 m
5 l
4 c
4 b
3 f
2 y
2 q
2 h
2 g
2 .
2 ,
1 w
1 v
1 P
1 j
grep -o "[^ ]" 12.log|awk '{S[$1]++}END{for(k in S) print S[k],k}'|sort -rn
[root@k8s-master tmp]# grep -o "[^ ]" 12.log|awk '{S[$1]++}END{for(k in S) print S[k],k}'|sort -rn
19 s
18 o
17 e
15 t
14 n
14 i
12 r
10 a
8 u
8 d
7 p
6 m
5 l
4 c
4 b
3 f
2 y
2 q
2 h
2 g
2 .
2 ,
1 w
1 v
1 P
1 j