shell经典笔试题目总结
守望者整理了一些高手的博客记录的shell面试题分享给大家,有些比较有意思,帮助大家面试或则学习shell编程的学习例子
一 文件内容如下:
100
a 100
b -50
c -20
d -30
要求输出结果为:
100
a 100
200
b -50
150
c -20
130
d -30
一句话思路:用shell肯定是不行,因为是操作文件。用sed倒是可以操作文件,但有数学运算还要用到变量。所以,用awk应该是最好的。
awk 'NR==1{sum=$1;print $0}NR!=1{print $0;sum=sum-$2;print sum}' 内容文件
知识点:awk变量,域
二 文件内容如下:
123abc456
456def123
567abc789
789def567
要求输出:
456ABC123
123DEF456
789ABC567
567DEF789
sed 替换
由于(不是元字符,所以直接写(就表示(这个符号,而\(才表示包含什么的意思
echo "111(222)333"| sed 's/(\(.*\))/\1\1/'
\1 ===>\(.*\) =======》222 \1匹配括号里面的内容
http://blog.csdn.net/fdl19881/article/details/7800877
一句话思路:以点带面,文字处理,shell不行,awk不行,用sed加正则表达式
echo "123abc456" | sed 's/\(...\)\(...\)\(...\)/\3\2\1/;y/abc/ABC/'echo "AC456" | sed 's/[a-zA-Z]*[0-9]*/& passed/g' =>AC456 passed &表示前面匹配到的内容
sed匹配空格,tab
echo "test 3" | sed 's/^test[\t| ]\+3$/aaa/' ====》aaa
echo "test 3" | sed -r 's/^test[\t| ]+3$/aaa/' ====>aaa
??? sed -r's/({3})({3})({3})/\3\2\1/;y/abcdef/ABCDEF/'内容文件
知识点:-r 支持扩展的正则表达式,跟grep用-P类似。y其实就是tr只是写到sed里面更好看一些,sed的查找替换,当然还有正则中的分组。sed中的分组可以这么用,awk就不行了只能用&,而且分组数量不能超过9,即不会有\10出现。
三. 文件内容如下
1.1.1.1 11
1.1.1.1 22
1.1.1.1 33
1.1.1.1 44
2.2.2.2 11
2.2.2.2 22
2.2.2.2 33
2.2.2.2 44
要求使用sed及awk分别将文件输出:
1.1.1.1 11223344
2.2.2.2 11223344
一句话思路:这个没啥思路了,上面还分析分析用什么合适,这里面没的选了,人家都说了,就弄吧。
sed -r 'N;N;N;s/\n/ /g;s/(.*)(11 )(.*)(22 )(.*)(33 )(.*)(44)/\1\2\4\6\8/' 内容文件
知识点:N将文件的下一行读入模式空间,3个N就是读取下面三行进入当前模式空间,读进去的行依然保留换行,所以删除换行,后面的就不说了,你懂的。
awk '{sum[$1]=sum[$1]" "$2}END{for(var in sum)print var sum}'内容文件
知识点:awk数组,awk字符串赋值,使用for遍历awk数组。
四. 分析apache日志,给出当日访问ip的降序列表。
一句话思路:分析ip就要提取ip,提取的办法除了awk,还有个东西叫cut。
cut-d " " -f1 /etc/httpd/log/access_log|sort|uniq-c|sort-nr
知识点:cut命令,sort将汇总相同内容,uniq -c合并重复内容,并给出重复次数。sort-nr使用数字排序,默认是ascii,并且是降序,默认是升序。
awk '{sum++}END{for(var in sum)print ip sum}' /etc/httpd/log/access_log| sort -k2 -nr
知识点:awk数据,sort -k2 -nr 降序数字排序就不说了,-k参数指定使用哪个列进行排序。默认是自然是第一列。
五.亚瑟王环
有1到100的数字序列。有计数器每数到12,就将计数器指向的数字在亚瑟环中剔除,问该序列中最后剩下的数字是多少?
一句话思路:100,12的太复杂,就弄个10,2的,完成之后替换一下。。。。。。
最后的答案是:81 面试的时候你可以说是心算的(别脱口而出,稍微伪装一下),就是不知道行不行。
做计数器,当计数器到达12的时候就将一个数组中对应的值赋值为零。当所有数组中的数字还剩唯一的不为零的值的时候就是剩下的数字。
#/bin/bash
for i in {1..100};do
huan[$i]=$i
done #先初始化一个数组,其实用变量也行,个人喜好,用awk也行,但一篇内容一个shell有点不合适。
t=0#定义一个计数器
sum=0
while true;do #定义一个无限循环,因为确实不知道要数多少次。
for((i=1;i<101;i++));do
if [ ${huan[$i]} -gt 0 ];then#不等于零就把计数器加1
let t++
fi
if [ $t -eq 12 ];then#数到12就将数组中的数清零,同时计数器清零
huan[$i]=0
t=0
fi
done
for((i=1;i<101;i++));do#遍历数组,如果数组中只有一个数不为零就跳出循环
if [ ${huan[$i]} -gt 0 ];then
let sum++
sum=${huan[$i]}
fi
done
if [ $sum -eq 1 ];then
break
else
sum=0
fi
done
echo ${sum}
这篇的内容相对基础,主要集中在计划任务和find命令上面。
crontab 分时日月周 find命令的 exec 和 xargs 这是两个比较容易遗忘的知识点。
1、编写shell程序,实现自动删除50个账号的功能。账号名为stud1至stud50。
一句话思路:找出规律,循环解决
for((i=1;i<51;i++));do userdel -r stud$i ;done
知识点:for循环,当然是用while循环也是可以的,until也行。
2、某系统管理员需每天做一定的重复工作,请按照下列要求,编制一个解决方案:
第1列分钟1~59
第2列小时1~23(0表示子夜)
第3列日1~31
第4列月1~12
第5列星期0~6(0表示星期天)
第6列要运行的命令
下面是crontab的格式:
分 时 日 月 星期 要运行的命令
45 4 1,10,22 * * /usr/local/apache/bin/apachectl restart
上面的例子表示每月1、10、22日的4 : 45重启apache。
(1)在下午4 :50删除/abc目录下的全部子目录和全部文件;
(2)从早8:00~下午6:00每小时读取/xyz目录下x1文件中每行第一个域的全部数据加入到/backup目录下的bak01.txt文件内;
(3)每逢星期一下午5:50将/data目录下的所有目录和文件归档并压缩为文件:backup.tar.gz;
一句话思路:主要考验管理员对于计划任务的熟悉程度
crontab -e
50 16 * * * rm -rf /abc/*
* 8-18/1 * * * awk '{print $1 > "/backup/bak01.txt"}' /xyz/x1
50 17 * * 1 tar -czf backup.tar.gz /data
知识点:awk的输出重定向,当然用管道也是可以的。tar命令打包参数,这样做会有一个提示,只是去掉了目录不用理会。
3、gameser这个服务启动命令为./gameser服务,请写一个脚本,当服务宕掉,脚本自动拉起gameser服务。
一句话思路:进程管理
#!/bin/bash
while true;do
result=`ps aux | grep gameser | wc -l`
if [ $result -lt 2 ];then./gameser; fi
sleep 5
done
知识点:还可以使用pgrep命令。
4、linux crontab;请在3月23号21点18分的时候,重启服务器
一句话思路:计划任务+关机
crontab -e
18 21 23 3 * init 6
linux关机:
sync;sync;sync,init 0
init是所有进程的祖先,其进程号始终为1。init用于切换系统的运行级别,切换的工作是立即完成的。init 0命令用于立即将系统运行级别切换为0,即关机;init 6命令用于将系统运行级别切换为6,即重新启动。
知识点:可能会延展提问到最安全的关机命令,“写缓存”sync 最好两遍,有人说三遍,其实四遍也行,要不干脆还是别关机了!
5、你想每天23:00运行xxxx.sh脚本。并自动进行日志分析。第2天上班的时候看到分析结果 给出你的部属方案
一句话思路:计划任务,日志分析
0 23 * * * sh ****.sh;err=$?;logger -p cron.err $err
知识点:第一个参数一定要写零,否则在定义的23点里每分钟都会执行。计划任务只有当报错的时候才会以邮件形式发送给用户,所以这里使用logger命令将消息发送给日志服务器,这里只是发送了命令返回值,你可以随意发送内容,看你喜欢了。
6、要求:运行脚本输入两个数得到如下结果:
#sh xxx.sh 2 3
**
***
*****
一句话思路:看到这个第一反应就是循环呗。
#!/bin/bash
line1=$1
line2=$2
let line3=$1+$2
while [ $line1 -gt 0 ];do
echo -n \*
let line1=$line1-1
done
echo
while [ $line2 -gt 0 ];do
echo -n \*
let line2=$line2-1
done
echo
while [ $line3 -gt 0 ];do
echo -n \*
let line3=$line3-1
done
echo
知识点:如果你的第一反应是使用循环,那就进入一个死循环了,因为根本就没有规律。我们都知道,循环是依靠一定规律的。echo 的 -n参数。*在shell中是通配符,所以要加转义字符。(希望你能给出更好的解决方案!)
9、查找文件后缀是log的 三天前的文件删除
一句话思路:查找就一定是find
find / -name "*.log" -and -mtime +3 -exec rm -rf {} \;
知识点:-mtime+ 代表后面数字之外的,- 就是之内的。
10、写一个脚本将目录下大于100kb的文件移动到/tmp下
一句话思路:同上
find ./ -size +100k -exec mv {}/tmp \;
知识点:-exec{}\; 标准写法,没有好办法,背吧。
11 、日志如下统计访问IP最多的前10个
192.168.0.6 - - "GET /cacti/images/auth_login.gif HTTP/1.1" 200 21265 "" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.1)"
192.168.0.6 - - "GET /favicon.ico HTTP/1.1" 404 287 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.1)
这个题在前一篇中已经给出答案,这里就不再赘述。
http://7648853.blog.51cto.com/4990508/851407
12、过滤出当前目录下所有以字母(不区分大小写)开头的文件
一句话思路:过滤就是grep
ls | grep -P "^"
ls | grep -P -i "^"
知识点:正则表达式,使用-i参数让grep命令不区分大小写。
13、文件A.txt内容为"12:34:68",只输出A.txt中的"34"
一句话思路:提取内容就是awk
awk-F ":" '{print $2}' A.txt
知识点:awk 域,-F参数指定分隔符,默认分隔符是空格。
14、用sed命令实现直接将文件B.TXT中的所有123替换成345
一句话思路:没思路了,人家都说了用sed
sed -i 's/123/456/g' B.TXT
知识点:-i参数让sed修改文件,默认不修改源文件。题目中提到了所有字样,所以要使用g参数。
15、用sed修改文件mailbox.txt的20行的zhango为wang
一句话思路:命题作文sed,没有瞎想空间
sed -i '20s/zhango/wang/' mailbox.txt
知识点:上题是全局,这题规定了行。如果写成这样"/20/",就是正则表达式了。
16、正则表达式,IP地址的匹配,写一下
一句话思路:遥想当年,web开发程序员面试不出意外的第一道题。
({1,3}\.){1,3}(){1,3}
知识点:正则表达式,写个简单的,这个答案不严谨,但考虑到只是面试,所以将就将就也能用。
17、写出命令。统计日志文件weblog.log中 今天14:00~15:00的记录条数(时间格式:2011-01-01—15:30:11)
一句话思路:第一反应,这个要用awk,分析统计嘛。可真要用awk麻烦就大了。
sum14=`grep -c "2011-01-01-14" weblog.log`
sum15=`grep -c "2011-01-01-15" weblog.log`
echo $[$sum14+$sum15]
知识点:grep命令-c参数,统计匹配的行数。shell中的数学计算。
18、求一组数的最大值和最小值
一句话思路:运维越来越像开发了,冒泡法都有了。越来越难混了,一个运维不看手册,要看算法了。
知识点:去看书吧,看算法的。
19、将当前目录所有文件扩展名改为log
一句话思路:如果你的第一反应是使用find命令,那么恭喜你,你中了敌人的奸计,不是不能实现,是很麻烦。
linux查看目录的四种方法(ls只显示目录)
1.ls -d *
2. find . -type d -maxdepth 1
3.ls -F | grep '/$'
4.ls -l | grep '^d'
5.grep -P "(.*)(\..*)" 这种有缺陷就是不能过滤掉本身包含有.的目录
for file in `ls ./ | grep -P "(.*)(\..*)"`;doecho $file | mv $file `sed -r 's#(.*)(\..*)#\1.log#'`; done
for file in `ls ./ | grep -P "(.*)(\..*)"`;doecho $file | mv $file `echo ${file%.**}`.log; done
知识点:第一个方法中使用了sed,第二个方法中使用了字符操作,#从前向后数,%从后向前数。其实说白了,就是为了拼凑出 mv 参数1 参数2。其实很多时候,编写shell脚本的时候要学会反向推导,逆向思考。
还有一种方法是使用cut命令,但如果遇到文件有两个扩展名的情况下就会出现问题。redhat as4 安装完成后,在root目录下会生成install.loginstall.log.syslog这两个文件,如果使用cut就会出现错误。具体原因在这里就不说了。运维嘛,需要的是严谨!
20、用shell在/usr/local下 建立20个子目录 xunlei1-xunlei20,再在这个子目录下分别建255个子目录dir1-dir255,再在255个子目录下创建10000个文件xunlei1.html-xunlei10000.html
一句话思路:这有啥,{}大括号呗。
mkdir -p /usr/loca/xunlie{1..20}/dir{1..255}/
touch /usr/loca/xunlie{1..20}/dir{1..255}/xunlei{1..10000}.html
知识点:如果你就这么写上去,那你又中计了。为什么呢,因为超过了shell命令参数的最大限制。shell中参数的限制是:5452。所以要分着写。
这篇内容中所涉及的知识点比较多,设置的陷阱更是不少,可以感觉到出题人的挖空心思,可以考验出答题人对于系统,对于实际环境的管理能力及功底。
1.如下是对api接口日志的截取,存放在check.log文件中
22:57:36|check|por1|117.136.15.67|4|username|fail|5|29|
22:57:36|check|por1|183.1.94.215|4|username|succ|1644841971|14|
22:57:36|check|pro2|0.0.0.0| |username|succ|162885433|6|
22:57:36|check|por2|0.0.0.0|9|username|fail|-4038|0|
22:57:36|check|por3|120.11.82.19|2|username|fail|5|49|
22:57:36|check|por4|172.16.86.82|0|username|succ|1548062613|1|
22:57:36|check|por2|123.125.156.135|9| |succ|1632786393|1|
22:57:36|check|por5|124.231.21.100|5|username|succ|224803739|3|
22:57:36|check|por4|172.16.86.82|0|username|succ|1505887155|1|
22:57:36|check|por2|0.0.0.0|9|username|succ|1343846051|1|
22:57:36|check|por6|113.193.202.138|8|username|succ|1729273615|1|
22:57:36|check|por6|116.75.149.20|8|username|succ|1729981552|1|
22:57:36|check|por5|116.5.164.94|5|username|succ|214405328|1|
22:57:36|check|por2|0.0.0.0|9|username|succ|1433162137|1|
22:57:36|check|por3|218.69.6.30|5|username|succ|28725136|42|
22:57:36|check|por2|0.0.0.0|8| |fail|5|4|
22:57:36|check|por5|123.115.102.222|5|243905232|succ|243905232|1|
22:57:36|check|por4|172.16.86.82|0|1011711900|succ|1011711900|39|
日志各字段代表的意义如下:
时间|接口名称|使用该接口的产品名称|调用接口的IP地址|用户类型|用户账号名称|接口返回结果(succ or fail)|当接口返回结果为“succ”时,该字段为用
户唯一编号;当接口返回结果为“fail”时,该字段为接口返回的错误代号|接口执行时间(毫秒级别)
问题:请使用shell命令的组合得到每个产品调用该接口成功时接口的平均执行速度,并按照执行速度由低到高排序(注:用户类型和用户账号名称为空的访问不
计算在内),以如下格式输出:
pro1 :0.0714286
pro2 :0.3333333
pro3 :0.0238095
pro4 :0.0731707
pro5 :0.6
pro6 :1
第一步:
awk -F "|" '{a[$3]++}END{for(i in a){print i, a[i]}}' test.txt
统计出每个pro的数量
por5 3
por6 2
por1 2
por2 6
por3 2
por4 3
匹配succ的行
NF:表示当前行的字段数量$(NF-3) 匹配倒数第三列
一句话思路:有计算、有排序,awk是唯一选择。统计总数的同时,还要统计出现次数,最后进行计算。
awk -F "|" '$(NF-3)~/succ/{por[$3]=por[$3]+$(NF-1);sum[$3]++}END{for(var in por)print var" :"por/sum | " sort -k2 -nr"}' check.log
por[$3]=por[$3]+$(NF-1) 统计总数
sum[$3]++统计出现次数
知识点:awk数组,awk管道,为避免不等长使用NF变量
2.用一行命令实现:查找当前目录下(含子目录),文件内容中含有sina且文件名以".config"结尾的文件
一句话思路:批量按规则查找文件内容grep
grep -lr "sina" ./ | grep -P "(.*)(\.config$)"
知识点:grep -r 递归查找,-P支持perl正则表达式
3.用shell查询以“.”结尾的文件,并加上后缀“.ts”
一句话思路:在之前的曾经有过批量修改扩展名的实例,但这次有所不同,使用find命令就可以搞定
find ./ -name "*." -exec mv {} {}ts \;
知识点:find命令
4.假定某个web服务器访问log其中一行如下:
61.159.245.95 - - "GET / HTTP/1.1" 200 151 "" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT
6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3;
360SE)"
该LOG文件超过10万行,如果列出最后的10万行中请求最多前十位IP,显示如下的结果:
119 211.101.169.200
103 211.101.169.206
50 61.149.38.249
11 202.106.138.194
请用一行命令显示出上面的结果
一句话思路:之前有过类似的,这里不再赘述
awk '{ip[$1]++}END{for(var in ip)print ip,var |"sort -nr|head -n10"}' log
5.linux下ifconfig命令显示结果如下:
eth0 Link encap:EthernetHWaddr 00:0C:29:AA:E6:44
inet addr:192.168.213.128Bcast:192.168.213.255Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:feaa:e644/64 Scope:Link
UP BROADCAST RUNNING MULTICASTMTU:1500Metric:1
RX packets:39962 errors:0 dropped:0 overruns:0 frame:0
TX packets:27038 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:35108954 (33.4 MiB)TX bytes:6573610 (6.2 MiB)
Base address:0x2000 Memory:c9020000-c9040000
lo Link encap:Local Loopback
inet addr:127.0.0.1Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNINGMTU:16436Metric:1
RX packets:1833 errors:0 dropped:0 overruns:0 frame:0
TX packets:1833 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4840659 (4.6 MiB)TX bytes:4840659 (4.6 MiB)
执行如下命令
/sbin/ifconfig eth0|grep 'inet '|sed 's/^.*addr://g'|sed 's/ Bcast.*$//g'
请写出命令的输出结果
ip地址 犹豫了一下这个要不要写,在命令行里执行一下就行了。
6.多线程/多进程 程序同时访问相同的资源(例如:同时向一个文件里写数据)需要注意些什么?
至少注意文件锁,读锁与写锁
http://blog.chinaunix.net/uid-8478094-id-3995108.html
Shell脚本中并发线程以及并发数的控制
#!/bin/bash
for(( i = 0; i
do
{
commands1
}&
done
wait
commands2
&commands1在后台执行,wait并等到循环内容所有command都执行完以后才执行command2对于上面的代码,如果count值特别大的时候,我们应该控制并发进程的个数,不然会影响系统其他进程的运行,甚至死机。
下面的代码控制并发个数。其实是利用令牌原理实现,一个线程要运行,首先要拿到令牌在该代码中即read一行数据,读取不到数据就会暂停,否则就拿到数据就运行命令任务,完成后将令牌再放回,也即再在管道文件中写入一行数据,这里的数据是换行符,echo >&4。这样另外的线程就可以再读该数据(拿到令牌),并运行。
#!/bin/bash
tmpfile=$$.fifo #创建管道名称 #以进程ID号命名管道文件
mkfifo $tmpfile #创建管道
exec 4<>$tmpfile #创建文件标示4,以读写方式操作管道$tmpfile
rm $tmpfile #将创建的管道文件清除
thred=4 #指定并发个数
seq=(1 2 3 4 5 6 7 8 9 21 22 23 24 25 31 32 33 34 35) #创建任务列表
# 为并发线程创建相应个数的占位
{
for (( i = 1;i<=${thred};i++ ))
do
echo; #因为read命令一次读取一行,一个echo默认输出一个换行符,所以为每个线程输出一个占位换行
done
} >&4 #将占位信息写入管道
for id in ${seq[*]} #从任务列表 seq 中按次序获取每一个任务 或者用:for id in ${seq}
do
read #读取一行,即fd4中的一个占位符
(./ur_command ${id};echo >&4 ) & #在后台执行任务ur_command 并将任务 ${id} 赋给当前任务ur_command;任务执行完后在fd4种写入一个占位符 ,&表示该部分命令/任务 并行处理
done
wait #等待所有在此shell脚本中启动的后台任务完成
exec 4>&- #关闭管道
整个流程中read 和 echo 对fd4的交替写入和读取是并发处理的关键
可以想象 如果read 命令发现fd4中没有数据时 将等待fd4的数据
但是这有个缺点就是每个线程运行前都要拿到令牌,而且这个令牌的拿放是要消耗I/O的,有没有更好的方法实现?
可以用PV语句实现。也就是定义一个全局变量globleThread_num用来存放最大线程个数,还要有一个变量currentThread_num存放当前的线程个数,然后需要锁,当读取和改变currentThread_num的值的时候,需要锁住。
分享一个在Linux下模拟多线程的并发脚本,使用这个脚本可以同时批量在定义数量的服务器上执行相关命令,比起普通for/while循环只能顺序一条一条执行的效率高非常多,在管理大批服务器时非常的实用。
以下脚本功能是通过scp(也可选rsync)向上千台服务器传更新包,脚本运行后同时在后台有50个scp进程向服务器传包。
#!/bin/bash
ip=`cat iplist.txt|grep -v "#"|awk '{print $1}'` #过滤服务器IP
dir='/usr/local/src' #目标路径
thead_num=50 #自定义并发数,根据自身服务器性能或应用调整大小,开始千万别定义太大,避免管理机宕机
tmp_fifo_file="/tmp/$$.fifo" #以进程ID号命名管道文件
mkfifo $tmp_fifo_file #创建临时管道文件
exec 4<>$tmp_fifo_file #以读写方式打开tmp_fifo_file管道文件,文件描述符为4,也可以取3-9任意描述符
rm -f $tmp_fifo_file #删除临时管道文件,也可不删除
for ((i=0;i
do
echo "" #输出空行
done >&4 #输出重导向到定义的文件描述符4上
for i in $ip #循环所有要执行的服务器
do
read -u4 #从管道中读取行,每次一行,所有行读取完毕后执行挂起,直到管道有空闲的行
{
scp -P 1000 $1 $i:$dir #所有要批量执行的命令都放在大括号内,scp是一个简单实例,可替换任意其他命令及命令组,1000为服务器端的端口
sleep 3 #暂停3秒,给系统缓冲时间,达到限制并发进程数量
echo "" >&4 #再写入一个空行,使挂起的循环继续执行
}& #放入后台执行
done
wait #等待所有后台进程执行完成
exec 4>&- #删除文件描述符
exit 0
--------------------------------低调的分割线------------------------------------
如果管理机与其他服务器没有建立ssh信任,也可将expect自动应答命令添加到并发脚本的循环体当中,修改如下:
#!/bin/bash
ip=`cat iplist.txt|grep -v "#"|awk '{print $1}'`
dir='/usr/local/src'
answer="yes" #定义yes/no应答变量
passwd="123456" #服务器密码
thead_num=50
tmp_fifo_file="/tmp/$$.fifo"
mkfifo $tmp_fifo_file
exec 4<>$tmp_fifo_file
rm -f $tmp_fifo_file
for ((i=0;i
do
echo ""
done >&4
for i in $ip
do
read -u4
{
expect
spawn scp -P 1000 $1 $i:$dir
expect "(yes/no)?" {
send "$answer\r"
expect "Password:"
send "$passwd\r"
} "Password:" {send "$passwd\r"} "*host" {exit 1}
expect eof
EOF
sleep 3
echo "" >&4
}&
done
wait
exec 4>&-
exit 0
7.写脚本实现,可以用shell,perl等。把文件B中有的,但是文件A中没有的所有行,保存为文件C,并统计C的行数
diff B A | grep " C
8.脚本实现把/tmp/目录下所有创建超过7天的文件删除
find /tmp -mtime +7 -exec rm -rf {} \;
9.把1 2 3 4 5 6按如下格式输出
1
2
3
4
5
6
如何实现
echo 1 2 3 4 5 6 | sed "s# #\n#g"
10.设计一个shell程序,在2012年12月23日凌晨3点备份并压缩前一天/svn目录的所有内容,存放在/root/bak目录里,且文件名为如下形式svn.2008.05.06.tar.gz,试写脚本。
at 201212230300
at> find /svn -mtime +1 -and -mtime -2 -exec cp -r {} /root/bak \;
at> tar -czf svn.2008.05.06.tar.gz /root/bak
转载:http://president.blog.51cto.com/4990508/851407
http://president.blog.51cto.com/4990508/854249
http://president.blog.51cto.com/4990508/854647