已经练习了绝大部分的shell内容了,也应该好好准备面试的事了,下面在网上找了些题,可以拿来分析分析,顺便巩固下以前学的内容;
没有答案的慢慢找答案;
一、
1.有一个文件,里面有二列,第一列ip地址,第二列是时间,同一个ip可能出现多次,但时间不同.
文件类似下面的样子:
192.168.1.2 13:10
192.127.12.1 13.11
192.168.1.2 14:22
现要求写一脚本,显示出现最多的ip top 10
awk '{print $1}' file|sort|uniq -c|sort -nr|head -10
分析:
只是提取最多的IP,并没有要求包含时间,所以先提取该IP列进行下一步的处理;
然后利用sort排序,再用uniqu -c 统计次数并显示;
再用sort -nr 按由高到低的顺序排列,最后利用head 截取前10 排;
测试过程:
sort的 参数 n 代表compare according to string numerical value 根据字符串数值进行比较;
r 代表反转
不要 r 参数的话,后面可以改用tail 来取后十个,但就不能满足由高到低排列了;
2.假设Apache产生的日志文件为access.log,在Apache正在运行的时候,执行命令mv access.log access.bak
,执行完毕后,请问新的apache日志会打印到那里?为什么?
答: 新的日志会打印在access.bak中. 因为apache启动时,会找到access.log文件,随时准备向文件中追
加日志,虽然此时文件被改名,但是由于服务正在运行,
因为它的inode节点的位置没有变,程序打开的
fd仍然会指向原来的那个inode.不会因为文件名的改变而改变,但若重启服务器之后,系统就会检查
access.log文件是否存在,不存在,则创建.
3.在shell环境中,如何查看远程Linux系统运行了多少时间?
ssh 后面还可以 跟命令,太好了@@
4.处理一下文件内容,将域名取出并进行计数排数,如处理:
http://www.baidu.com/index.html http://www.baidu.com/1.html
http://www.baidu.com/2.html
http://post.baidu.com/index.html
http://mp3.baidu.com/index.html
http://www.baidu.com/3.html
http://post.baidu.com/2.html
得到如下结果:域名的出现次数,域名
4 www.baidu.com
2 post.baidu.com
1 mp3.baidu.com
shell程序如下:
方法一: #cat file|sed -e 's/http:\/\///' -e 's/\/.*//'|sort|uniq -c|sort -nr|head -10
Loong:/home/yee/shell# cat sort1.sh|sed -e 's/http:\/\///' 利用sed去掉http://,反斜杠表转义
www.baidu.com/index.html
www.baidu.com/1.html
www.baidu.com/2.html
post.baidu.com/index.html
mp3.baidu.com/index.html
www.baidu.com/
post.baidu.com/2.html
Loong:/home/yee/shell# cat sort1.sh|sed -e 's/http:\/\///' -e 's/\/.*//' 接着去掉/ * 后面的内容
www.baidu.com
www.baidu.com
www.baidu.com
post.baidu.com
mp3.baidu.com
www.baidu.com
post.baidu.com
Loong:/home/yee/shell# cat sort1.sh|sed -e 's/http:\/\///' -e 's/\/.*//'|sort|uniq -c|sort -nr
4 www.baidu.com
2 post.baidu.com
1 mp3.baidu.com
方法二: #awk -F/ '{print $3}' file|sort -r|uniq -c|awk '{print $1 "\t",$2}'
Loong:/home/yee/shell# awk -F/ '{print $3}' sort1.sh|sort -r|uniq -c|awk '{print $1 "\t",$2}' 以指定的 / 为分隔符进行输出
4 www.baidu.com
2 post.baidu.com
1 mp3.baidu.com
Loong:/home/yee/shell#
方法三,步骤详解:
Loong:/home/yee/shell# awk 'BEGIN {FS="//"} {print $2}' sort1.sh 按指定分隔符截取内容,下同,共两次
www.baidu.com/index.html
www.baidu.com/1.html
www.baidu.com/2.html
post.baidu.com/index.html
mp3.baidu.com/index.html
www.baidu.com/
post.baidu.com/2.html
Loong:/home/yee/shell# awk 'BEGIN {FS="//"} {print $2}' sort1.sh > sort2.sh
Loong:/home/yee/shell# awk 'BEGIN {FS="/"} {print $1}' sort2.sh > sort3.sh
Loong:/home/yee/shell# cat sort3.sh
www.baidu.com
www.baidu.com
www.baidu.com
post.baidu.com
mp3.baidu.com
www.baidu.com
post.baidu.com
Loong:/home/yee/shell# sort -nr sort3.sh
www.baidu.com
www.baidu.com
www.baidu.com
www.baidu.com
post.baidu.com
post.baidu.com
mp3.baidu.com
Loong:/home/yee/shell# sort -rn sort3.sh | uni
unicode_start unicode_stop uniq unix_chkpwd unix_update
Loong:/home/yee/shell# sort -rn sort3.sh | uniq -c
4 www.baidu.com
2 post.baidu.com
1 mp3.baidu.com
Loong:/home/yee/shell#
5.如果得到随机的字串,长度和字串中出现的字符表可定义并将字串倒序显示,如把0123456789作为基准的
字串字符表,产生一个6位的字串642031,打印出的字符串为130246,可使用bash/perl/php/c任一种。
bash程序如下:
#
awk -v count=6 'BEGIN {srand();
str="0123456789";
len=length(str);
for(i=count;i>0; i--)
marry[i]=substr(str,int(rand()*len),1);
for(i=count;i>0;i--)
printf( "%c",marry[i]);
printf("\n");
for(i=0;i<=count;i++)
printf("%c",marry[i]);
printf("\n")}'
改写成awk脚本的方式
#! /bin/awk -f
#usage:basename count=n str=string
BEGIN{
srand();
}
{
len=length(str);
for(i=count;i>0;i--)
marry[i] = substr(str,int(rand() * len),1);
for(i=count;i>0;i--)
printf("%c",marry[i]);
printf("\n");
for(i=0;i<=count;i++)
printf("%c",marry[i]);
printf("\n----------------------------------\n");
}
输出结果:838705
507838
6.如何查看当前Linux状态。如cpu使用,内存使用,负载情况等
答:linux 中,"/proc"是个伪文件目录,不占用系统空间,及时反应出内存现在使用的进程情况
其中许多文件都保存系统运行状态和相关信息。
对于/proc可以浏览其文件内容:
cpuinfo 主机cpu信息
filesystems 文件系统信息
meninfo 主机内存信息
version Linux版本信息
diskstatus 磁盘负载情况
另外top命令可以动态的显示出当前系统进程用户的使用情况,free命令可以查看内存信息
ps 查看进程情况。
7.比如,ext2文件系统,如果异常死机,开机如何修复文件系统?
答: 如果异常死机,如断电,通知机房的人开机之后,我们需要远程修复,检查文件系统。除了
/ 分区之外,其他分区:umount /home
fsck -y /home
/ 分区需要开机之后由机房人员检查。随后我们登录并扫描/home分区
fsck - check and repair a Linux file system
fsck [-sAVRTMNP] [-C [fd]] [-t fstype] [filesys...] [--] [fs-specific-options]
The exit code returned by fsck is the sum of the following conditions:
0 - No errors
1 - File system errors corrected
2 - System should be rebooted
4 - File system errors left uncorrected
8 - Operational error
16 - Usage or syntax error
32 - Fsck canceled by user request
128 - Shared library error
-y For some filesystem-specific checkers, the -y option will cause the fs-specific fsck
to always attempt to fix any detected filesystem corruption automatically.
8.如何检查一个进程所使用的文件句柄?
答:看这里面/proc/进程号/fd/ 的文件个数就行了
Loong:/proc/6918/fd# ll
总计 0
lrwx------ 1 root root 64 11-20 11:32 0 -> /dev/pts/2
lrwx------ 1 root root 64 11-20 11:32 1 -> /dev/pts/2
lrwx------ 1 root root 64 11-20 11:32 2 -> /dev/pts/2
lrwx------ 1 root root 64 11-20 11:32 255 -> /dev/pts/2
9.查看Apache的进程数。
wc -l wc -l 统计行数
用法:
wc - print newline, word, and byte counts for each file
-c, --bytes
print the byte counts
-m, --chars
print the character counts
-l, --lines
print the newline counts
--files0-from=F
read input from the files specified by NUL-terminated names in file F
-L, --max-line-length
print the length of the longest line
-w, --words
print the word counts
10.如何统计apache的每秒访问数?
tail access_log|awk '{print $1,$4}'
其中文件在:/etc/httpd/access_log
11.说明一下/proc/sys子目录的作用
答:该子目录的作用是
报告各种不同的内核参数,并让你能交互的更改其中某些。与/proc中所有
其他文件不同,该目录中的某些文件可以写入,不过针对root。一下是该子目录的两个最常见
的用途:
(1)允许路由:即便是Mandrakelinux 默认的内核也是允许路由的。你必须显式允许它这么做
为此:#echo 1 >/proc/sys/net/ipv4/ip_forward.
如果您要禁用,则让上述1改为0
(2)阻止ip欺骗:ip欺骗会让人认为某个来自于外部的某个数据包来自于它到达的那个接口,
这一技术常被crack利用。你可以阻止这种入侵:
#echo 1 >/proc/sys/net/ipv4/conf/all/rp_filter.
这次改变仅由系统运行时有效,系统重启后,会改变为默认值。你可以将以上命令添加到
/etc/rc.d/rc.local中,启动就会运行。另一方法:修改/etc/sysctl.conf
写一个登录shell文件,输入6次错误的用户名或密码不能登录,输入xxx用户,xxx密码登录成功
shell脚本
#!/bin/bash
flag=0;
for ((i=1;i<7;i++))
do
echo -n "please input your name:";
read username;
echo -n "please input your password:";
read password;
echo -n "your name is "
echo $username
echo -n "your password is ";
echo $password;
if [ $username = "user" -a $password = "pswd" ]
then
echo "login success!";
flag=1;
break;
fi
echo "your name or password wrong! Try it again.";
done
if [ "$flag" -eq "0" ]
then
echo "you have tried 6 times.login fail!"
fi
方法二:
while
do
......
done
1 #!/usr/bin/bash
2
3 i=0
4 read -p "please input your login name:" name
5 while [ $name == 'lijy' ]
6 do
7 while [ $i -lt 6 ]
8 do
9 read -p "your password is :" passwd
10 if [ $passwd == '123' ]
11 then
12 echo "congratulations to you, login successfully"
13 exit 0 0表示成功 ,后退出;
14 else
15 echo "password is wrong, please try again"
16 ((i+=1)) 自加的实现
17 fi
18 done
19 exit 0
20 done
21 echo "no username matched, please check your input"
输出: Loong:/home/yee/shell# sh login1.sh
please input your login name:lijy
your password is :123
congratulations to you, login successfully
Loong:/home/yee/shell# sh login1.sh
please input your login name:upt
no username matched, please check your input
Loong:/home/yee/shell# sh login1.sh
please input your login name:lijy
your password is :yuo
password is wrong, please try again
your password is :fhhj
password is wrong, please try again
your password is :jkk
password is wrong, please try again
your password is :iiooo
password is wrong, please try again
your password is :ioo
password is wrong, please try again
your password is :i
password is wrong, please try again
Loong:/home/yee/shell#
将红色部分修改一下即可使用 until 条件
do
...
done
方法三:
使用for 条件判断,do ...... done ,函数调用,if 混合实现:
1 #!/usr/bin/bash
2
3
4 i=0
5 read -p "please input your login name:" name
6 if [ $name == 'lijy' ]
7 then
8 for(( ;i<6;i++))
9 do
10 function judge()
11 {
12 read -p "your password is :" passwd
13 if [ $passwd -eq "123" ]
14 then
15 echo "congratulations to you, login successfully"
16 exit 0
17 else
18 echo "password is wrong, please try again"
19 fi
20 }
21 judge
22 done
23 else
24 echo "no username matched, please check your input"
25 fi
测试输出:
Loong:/home/yee/shell# sh -x login.sh
+ i=0
+ read -p 'please input your login name:' name
please input your login name:lijy
+ '[' lijy == lijy ']'
+ (( 1 ))
+ (( i<6 ))
+ judge
+ read -p 'your password is :' passwd
your password is :123
+ '[' 123 -eq 123 ']'
+ echo 'congratulations to you, login successfully'
congratulations to you, login successfully
+ exit 0
Loong:/home/yee/shell# sh -x login.sh
+ i=0
+ read -p 'please input your login name:' name
please input your login name:yu
+ '[' yu == lijy ']'
+ echo 'no username matched, please check your input'
no username matched, please check your input
Loong:/home/yee/shell# sh -x login.sh
+ i=0
+ read -p 'please input your login name:' name
please input your login name:lijy
+ '[' lijy == lijy ']'
+ (( 1 ))
+ (( i<6 ))
+ judge
+ read -p 'your password is :' passwd
your password is :67
+ '[' 67 -eq 123 ']'
+ echo 'password is wrong, please try again'
password is wrong, please try again
+ (( i++ ))
+ (( i<6 ))
+ judge
+ read -p 'your password is :' passwd
your password is :89
+ '[' 89 -eq 123 ']'
+ echo 'password is wrong, please try again'
password is wrong, please try again
+ (( i++ ))
+ (( i<6 ))
+ judge
+ read -p 'your password is :' passwd
your password is :89
+ '[' 89 -eq 123 ']'
+ echo 'password is wrong, please try again'
password is wrong, please try again
+ (( i++ ))
+ (( i<6 ))
+ judge
+ read -p 'your password is :' passwd
your password is :990
+ '[' 990 -eq 123 ']'
+ echo 'password is wrong, please try again'
password is wrong, please try again
+ (( i++ ))
+ (( i<6 ))
+ judge
+ read -p 'your password is :' passwd
your password is :899
+ '[' 899 -eq 123 ']'
+ echo 'password is wrong, please try again'
password is wrong, please try again
+ (( i++ ))
+ (( i<6 ))
+ judge
+ read -p 'your password is :' passwd
your password is :900
+ '[' 900 -eq 123 ']'
+ echo 'password is wrong, please try again'
password is wrong, please try again
+ (( i++ ))
+ (( i<6 ))
Loong:/home/yee/shell# sh login.sh