linux运维初级班课前综合考试及参考答案20110529
#########################################################
#《老男孩linux就业培训中心-初级班第七期课前考试及课上讲解
#shell脚本编程实战模拟考试
#date:2011-5-29
#出题人:老男孩
#QQ:31333741 MAIL:[email protected]
#blog: http://oldboy.blog.51cto.com
#psite: http://oldboy.cc(即将开放)
##########################################################
问题1、实现每分钟检查一次apache进程,如果进程不存在打印数字1,存在打印数字0。
提示:
1、apache进程数获取命令 ps -ef|grep http|wc -l。
2、判断条件如果http进程数量大于0,即认为进程存在。
要求:
1.请使用if语句加定时任务实现。
2.请使用while语句实现
解答:
[root@oldboy-B scripts]# cat judgethttp.sh
#!/bin/sh
httppronum=`ps -ef|grep http|grep -v grep|wc -l`
#if [ `ps -ef|grep http|wc -l` -gt 0 ] #====这样写也是可以的。
if [ $httppronum -gt 0 ]
then
echo 0
else
echo 1
fi
提示:以上脚本执行结果是不对的?不知道你们发现没有?执行结果httppronum=`ps -ef|grep http|grep -v grep|wc -l`
不符合要求,而直接命令行ps -ef|grep http|grep -v grep|wc -l执行又是对的?到底是什么原因呢?请见下文?
====此处学生提问====
为什么老师的脚本开头写的是#!/bin/sh而不是#!/bin/bash
解答:因为在Centos和RedHat Linux系统 /bin/sh为/bin/bash软链接,就是说是同一个。
[root@oldboy-B scripts]# ll /bin/sh
lrwxrwxrwx 1 root root 4 04-23 16:29 /bin/sh -> bash
[root@oldboy-B scripts]# ll /bin/bash
-rwxr-xr-x 1 root root 735004 2009-01-22 /bin/bash
提示:
Bash 是 GNU/Linux 默认的 Shell 和 Bourne shell (sh) 兼容,而且采取了Korn shell (ksh) 和
C shell (csh) 的特色。符合 IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools 标准。Centos和
RedHat Linux下默认的Shell均为bash。因此,在写shell脚本的时候,我们的脚本的开头也可以不加
#!/bin/bash。但如果当前的shell非你默认的shell时,比如tcsh,那么就必须要写#!了。
建议大家最好都加上开头语言标识。
使用while守护进程方式实现(不用定时任务)
[root@oldboy-A scripts]# /application/apache/bin/apachectl start #===>启动apache
[root@oldboy-A scripts]# ps -ef|grep http|grep -v grep #===>查看apache进程
root 3675 1 1 19:06 ? 00:00:00 /application/apache2.2.17/bin/httpd -k start
apache 3684 3675 0 19:06 ? 00:00:00 /application/apache2.2.17/bin/httpd -k start
apache 3686 3675 0 19:06 ? 00:00:00 /application/apache2.2.17/bin/httpd -k start
apache 3688 3675 0 19:06 ? 00:00:00 /application/apache2.2.17/bin/httpd -k start
apache 3690 3675 0 19:06 ? 00:00:00 /application/apache2.2.17/bin/httpd -k start
[root@oldboy-A scripts]# cat judgeweb-while.sh #===>查看进程的脚本
#!/bin/sh
httpnum=`ps -ef|grep http|grep -v grep|wc -l`
while true
do
#if [ `ps -ef|grep http|wc -l` -gt 0 ] #====这样写也是可以的。
if [ $httpnum -gt 0 ]
then
echo 0
else
echo 1
fi
sleep 60
done
[root@oldboy-A scripts]# sh judgeweb-while.sh #===>执行看结果,返回0表示存在http进程
0
0
0
[root@oldboy-A scripts]# pkill httpd #===>杀死apache进程然后进行测试
[root@oldboy-A scripts]# ps -ef|grep http|grep -v grep #===>http进程不存在了
[root@oldboy-A scripts]# sh judgeweb-while.sh #===>执行看结果,返回1表示存在http进程
1
1
1
=============以下是学生的不同语法脚本===============
#!/bin/bash
#filename:while1
httpdport=`ps -ef|grep http|grep -v grep|wc -l`
while true
do
if (( "$httpdport" > 0 )) #======这是(())的语法写法
then
echo "1"
else
echo "0"
fi
sleep 60
done
--------------------------------------------------
问题2、已知如下命令及返回结果,请问 echo $user 的返回的结果为( )。并解释为什么?
[oldboy@test ~]$ cat test.sh
user=`whoami`
[oldboy@test ~]$ sh test.sh
[oldboy@test ~]$ echo $user
(互动百科面试题)
--------------------------------------------------
问题3. 从ett.log文件中提取包含"WARNING"或"UNKNOWN",同时不包含"OK"的行,然后提取以":"分割的第 3个字段
WARNING:UNKNOWN:OK:CRITICAL
WARNING:UNKNOWN:NO:OLDBOY
WARNING:NO:OLDBOY:QINGYUN
UNKNOWN:OK:CRITICAL::CRITICAL
(百度面试题)
解答;
步骤一:
[root@oldboy-B scripts]# egrep "WARNING|UNKNOWN" ett.log
WARNING:UNKNOWN:OK:CRITICAL
WARNING:UNKNOWN:NO:OLDBOY
WARNING:NO:OLDBOY:QINGYUN
UNKNOWN:OK:CRITICAL::CRITICAL
步骤二:
[root@oldboy-B scripts]# egrep "WARNING|UNKNOWN" ett.log|grep -v OK
WARNING:UNKNOWN:NO:OLDBOY
WARNING:NO:OLDBOY:QINGYUN
步骤三:
方法1:
[root@oldboy-B scripts]# egrep "WARNING|UNKNOWN" ett.log|grep -v OK |awk -F ":" '{print $3}'
NO
OLDBOY
方法2:
[root@oldboy-B scripts]# egrep "WARNING|UNKNOWN" ett.log|grep -v OK |cut -d: -f3
NO
OLDBOY
--------------------------------------------------
问题4.已知oldboy.txt内容为
i am oldboy! my qq number is 31333741
请把oldboy.txt中小写字母转换成的写字母
[root@oldboy-B scripts]# echo 'i am oldboy! my qq number is 31333741' >oldboy.txt
法1:
[root@oldboy-B scripts]# cat oldboy.txt |tr a-z A-Z
I AM OLDBOY! MY QQ NUMBER IS 31333741
[root@oldboy-B scripts]# cat oldboy.txt |tr "a-z" "A-Z"
I AM OLDBOY! MY QQ NUMBER IS 31333741
[root@oldboy-B scripts]# cat oldboy.txt |tr "[a-z]" "[A-Z]"
I AM OLDBOY! MY QQ NUMBER IS 31333741
[root@oldboy-B scripts]# cat oldboy.txt |tr [a-z] [A-Z]
I AM OLDBOY! MY QQ NUMBER IS 31333741
[root@oldboy-B scripts]# cat oldboy.txt
i am oldboy! my qq number is 31333741
提示:上面为不同的写法,tr的命令很好用,建议大家好好总结下。
这里也分享一个老男孩曾经写的生产环境使用tr的一个函数脚本。记住tr命令很有用。
function check_web_url()
#检查URL
{
wait #====>wait函数,内容见下面。
echo '检查url...!.'
for ((i=0; i<`echo ${#web_url_list[*]}`; i++))
do
judge=($(curl -I -s --connect-timeout 5 ${web_url_list[$i]}|head -1|tr "\r" "\n"))
if [[ "${judge[1]}" == '200' && "${judge[2]}"=='OK' ]]
then
action "${web_url_list[$i]}" /bin/true
else
action "${web_url_list[$i]}" /bin/false
echo -n "retrying again...";sleep 3;
judgeagain=($(curl -I -s --connect-timeout 10 ${web_url_list[$i]}|head -1|tr "\r" "\n"))
if [[ "${judgeagain[1]}" == '200' && "${judgeagain[2]}"=='OK' ]]
then
action "${web_url_list[$i]},retried again" /bin/true
else
action "${web_url_list[$i]},retried again" /bin/false
fi
fi
sleep 1;
done
}
function wait()
{
echo -n '3秒后,执行以下操作';
for ((i=0;i<3;i++))
do
echo -n ".";sleep 1
done
echo
}
解读:这是一个检查URL是否正常的一个生产环境使用的函数脚本,很实用。不过还需要有能力才能驾御
它呦,有想用,确弄不太明白的朋友可以联系我。。
--------------------------------------------------
问题5.如何得到RedHat Linux系统的下列信息,内核版本,发行版本?(搜狐畅游面试题)
解答:
[root@oldboy-B scripts]# uname -a
Linux oldboy-B 2.6.18-164.el5 #1 SMP Thu Sep 3 03:33:56 EDT 2009 i686 i686 i386 GNU/Linux
[root@oldboy-B scripts]# uname -r
2.6.18-164.el5
[root@oldboy-B scripts]# cat /etc/issue
CentOS release 5.4 (Final)
Kernel \r on an \m
[root@oldboy-B scripts]# cat /etc/redhat-release
CentOS release 5.4 (Final)
--------------------------------------------------
问题6.下面是一台RedHat Linux系统服务器执行uptime命令的输出结果,请解释各字段的含义(搜狐畅游面试题)
13:33:53 up 11 days,20:08,3 users,load average: 0.07,0.05,0.00
暂略
问题7.在RedHat/Centos Linux系统中,如何将oldboy.tar.gz压缩文件解压到指定的目录/home/oldboy/下(搜狐畅游面试题)
解答:
tar zxvf oldboy.tar.gz -C /home/oldboy/
提示:tar 是5星命令 请同学们必须熟练掌握了。详细总结见老男孩的命令教案
--------------------------------------------------
问题8.在RedHat/Centos Linux系统中,怎样查询/home/oldboy.txt文件中包含SOHU或CYOU的字符串?(搜狐畅游面试题)
解答:
[root@oldboy-B scripts]# echo 'SHHU OLDBOY' >>oldboy.txt
[root@oldboy-B scripts]# echo 'CYOU my love' >>oldboy.txt
[root@oldboy-B scripts]# cat oldboy.txt
i am oldboy! my qq number is 31333741
SHHU OLDBOY
CYOU my love
法一:
[root@oldboy-B scripts]# grep -E "SOHU|CYOU" oldboy.txt
CYOU my love
[root@oldboy-B scripts]# echo 'SOHU OLDBOY' >>oldboy.txt
[root@oldboy-B scripts]# echo 'sohu bestchaoliang' >>oldboy.txt
[root@oldboy-B scripts]# grep -E "SOHU|CYOU" oldboy.txt
CYOU my love
SOHU OLDBOY
拓展:不区分大小写的过滤
[root@oldboy-B scripts]# grep -Ei "SOHU|CYOU" oldboy.txt
CYOU my love
SOHU OLDBOY
sohu bestchaoliang
[root@oldboy-B scripts]# cat oldboy.txt
i am oldboy! my qq number is 31333741
SHHU OLDBOY
CYOU my love
SOHU OLDBOY
sohu bestchaoliang
--------------------------------------------------
问题9.在RedHat/Centos Linux系统上,某个进程占用了tcp的7777端口,如何得到此进程的ID?(搜狐畅游面试题)
解答:
法1:
[root@oldboy-B scripts]# lsof -i tcp:7777
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
sshd 1548 root 3u IPv6 4706 TCP *:7777 (LISTEN)
sshd 1804 root 3u IPv6 5737 TCP localhost:7777->localhost:jwclient (ESTABLISHED)
sshd 1806 oldboy 3u IPv6 5737 TCP localhost:7777->localhost:jwclient (ESTABLISHED)
[root@oldboy-B scripts]# lsof -i :7777
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
sshd 1548 root 3u IPv6 4706 TCP *:7777 (LISTEN)
sshd 1804 root 3u IPv6 5737 TCP localhost:7777->localhost:jwclient (ESTABLISHED)
sshd 1806 oldboy 3u IPv6 5737 TCP localhost:7777->localhost:jwclient (ESTABLISHED)
法2:
[root@oldboy-B scripts]# netstat -lntup|grep 7777
tcp 0 0 :::7777 :::* LISTEN 1548/sshd
提示:lsof是个不错的命令,老男孩经常使用。 有机会给大家分享使用lsof解决问题是的生产实战案例。
--------------------------------------------------
问题10.在RedHat/Centos linux中swap的作用?,swap一般分多大?(慧聪网面试题)
--------------------------------------------------
解答:
测试准备:
[root@oldboy-B scripts]# pwd
/server/scripts
[root@oldboy-B scripts]# touch oldboy.HTM chaoliang.HTM chenyan.HTM qingyun.HTM CAO.HTM guoxing.HTM dong.HTM
[root@oldboy-B scripts]# ls -l *.HTM
-rw-r--r-- 1 root root 0 05-29 00:15 CAO.HTM
-rw-r--r-- 1 root root 0 05-29 00:15 chaoliang.HTM
-rw-r--r-- 1 root root 0 05-29 00:15 chenyan.HTM
-rw-r--r-- 1 root root 0 05-29 00:15 dong.HTM
-rw-r--r-- 1 root root 0 05-29 00:15 guoxing.HTM
-rw-r--r-- 1 root root 0 05-29 00:15 oldboy.HTM
-rw-r--r-- 1 root root 0 05-29 00:15 qingyun.HTM
使用cat非交互方式生成改名脚本renamefile.sh:
cat >renamefile.sh <
do
newfile=\`echo \$file | tr A-Z a-z\`
mv \$file \$newfile
done
EOF
提示:此处提到这个目的是让大家熟悉下cat非交互方式输入内容的方法,这个方法常用来在脚本中使用。
注意:`及$符号需要转义 如:\`和\$
查看脚本内容:
[root@oldboy-B scripts]# cat -n renamefile.sh
1 for file in `ls *.HTM`
2 do
3 newfile=`echo $file | tr A-Z a-z`
4 mv $file $newfile
5 done
第1行遍历当前目录找出符合条件的.HTM文件
第3行定义变量newfile保存新的文件名,tr要用好(昨天考试过的),注意``(tab上面的键)
这两个符号内的都会被执行,然后赋值给newfile。
第4行,执行mv进行重命名。搞定。
[root@oldboy-B scripts]# cat renamefile.sh
for file in `ls *.HTM`
do
newfile=`echo $file | tr HTM htm` #===这个更符合题目要求
#newfile=`echo $file | tr A-Z a-z` #===这个也会同时把文件名大写改掉
mv $file $newfile
done
[root@oldboy-B scripts]# sh renamefile.sh
[root@oldboy-B scripts]# ls -l *.HTM
ls: *.HTM: 没有那个文件或目录
[root@oldboy-B scripts]# ls -l *.htm
-rw-r--r-- 1 root root 0 05-29 00:15 cao.htm
-rw-r--r-- 1 root root 0 05-29 00:15 chaoliang.htm
-rw-r--r-- 1 root root 0 05-29 00:15 chenyan.htm
-rw-r--r-- 1 root root 0 05-29 00:15 dong.htm
-rw-r--r-- 1 root root 0 05-29 00:15 guoxing.htm
-rw-r--r-- 1 root root 0 05-29 00:15 oldboy.htm
-rw-r--r-- 1 root root 0 05-29 00:15 qingyun.htm
可以看到所有大写的HTM都被改成了小写htm。
========以下是学生做的方法===========
法2:
[root@oldboy-A scripts]# cat renamefile2.sh
#!/bin/sh
#create by oldboy
#qq 31333741
for filename in `ls *.HTM`
do
mv $filename `echo $filename|tr HTM htm`
done
法3:
[root@oldboy-A scripts]# cat renamefile3.sh
#!/bin/bash
#create by oldboy
#qq 31333741
#filename:filename.sh
for fname in *
do
f=$(echo $fname | tr A-Z a-z)
if [[ "$fname" != "$f" ]] #====这里是不同的判断语法[[]]用法
then
mv $fname $f
fi
done
最后,由于个人水平及时间关系,老男孩这里给的参考答案未必都准确,欢迎大家一起交流讨论,共同进步。
===================================================================