shell实例总结
-eq ? ? ? ? ? //等于
-ne ? ? ? ? ? //不等于
-gt ? ? ? ? ? ?//大于 (greater )
-lt ? ? ? ? ? ?//小于 ?(less)
-ge ? ? ? ? ? ?//大于等于
-le ? ? ? ? ? ?//小于等于
/********************************************************************************************************************************/
1. 設計一個shell程序,在每月第一天備份并壓縮/etc目錄的所有內容,存放在/root/bak目錄里,且文件名為如下形式yymmdd_etc,yy為年,mm為月,dd為日。Shell程序fileback存放在/usr/bin目錄下
1)首先編寫備份文件的腳本fileback.sh
2) 使用Cron表達式
創建包含cron表達式的task文件task.cron 0 0 1 * * /root/fileback.sh 使用一下命令啟動定時任務 # crontab task.cron
PS:
使用以下命令查看和刪除Cron表:
# crontab -l ? //查看Cron表
0 1 * * * /root/fileback.sh
# crontab -r ?//刪除Cron表
?
2.編寫shell程序,實現自動刪除50個賬號的功能。賬號名為stud1至stud50。
#!/bin/bash i=1 while [ $i -lt 50 ] doif [ $i -ne 50 ]thenuserdel stud0${i}elseusedel stud${i}fii=`expr $i + 1` done3.設計一個shell程序,添加一個新組為class1,然后添加屬于這個組的? ? ? 30個用戶,用戶名的形式為stdxx,其中xx從01到30。
#!/bin/bash groupadd class1 for ((i=1;i<=30;i++)) do if [ $i -lt 10 ];then username="std0"$i else username="std"$i fi useradd -G class1 $username done注意-G:指定用戶所屬的附加群組。4.判斷一文件是不是字符設備文件,如果是將其拷貝到 /dev 目錄下。
#! /bin/bash #cp.shecho ?-e "please input filename /n" read FILENAME if[ -c $FILENAME ] thencp $FILENAME /dev elseecho "It's not Charactor device file" fi注意:其中有[ -c FILENAME ]這個命令就是判斷FILENAME是否是字符設備,如果是為真;如果不是為假;
/********************************************************************************************************************************/
1.查找當前目錄中所有大于500M的文件,把這些文件名寫到一個文本文件中,并統計其個數。
find ./ -size +500M -type f | tee file_list | wc -l
2.在目錄/tmp下找到100個以abc開頭的文件,然后把這些文件的第一行保存到文件new中。
for filename in `find /tmp -type f -name "abc*"|head -n 100`
do
sed -n '1p' $filename>>new
done
3.把文件b中有的,但是文件a中沒有的所有行,保存為文件c,并統計c的行數。
grep -xvf a b | tee c | wc -l
4.判斷一文件是不是塊或字符設備文件,如果是將其拷貝到 /dev 目錄下
read -p "input a file:" filename
if [ -b $filename -o -c $filename ]
then
????cp $filename /dev/
fi
5.每隔10分鐘監控一次,監控/usr下如果大于5G,發郵件給管理員
#!/bin/bash
while true
do
????sleep 600
????n=$(du -s /usr | cut -f1)
????if [ $n -gt 5242880 ]
????then
????????mail -s "greater"?filwsyl@gmail.com?< ~/filename #將文件filename的內容發送出去。
????fi
done
6.從a.log文件中提取包含"WARNING"或"FATAL",同時不包含"IGNOR"的行,然后提取以":"分割的第5個字段
grep -E 'WARNING|FATAL' a.log | grep -v IGNOR | awk -F ":" '{print $5}'
7.編寫一個腳本,進行簡單的減法運算,要求提示輸入變量
#!/bin/bash
read -p "input a number:" num1
read -p "input another number:" num2
let "num3=num1-num2"
echo $num3
8.把某個目錄下的文件擴展名改為bat,再以時間為文件名壓縮打包存放到某個目錄。
#!/bin/bash
for file in $(ls $1)
do
????new_file=${file%.*}.bat
????mv ./$1/$file ./$1/$new_file
????tmp=$(date +%y)
????tar cvf ./$tmp.tar ./$1
done
9.從網上下載一個文件,保存到指定目錄
#!/bin/bash
url=http://rs1.bn.163.com/ent/2009/05/20_canquedege.wma
dir=~/下載
wget -P $dir $url
10.判斷一個數是不是完數。打印出1-1000之間的完數。完數就是約數的和等于自身2倍的數。(6,28,496)
#!/bin/bash
sub()
{
????i=1;
????sum=0;
????while [ $i -le $num ]
????do
????????let "m=num%i"
????????if [ $m -eq 0 ]
????????then
????????????let "sum=sum+i"
????????fi
????????let "i=i+1"
????done
????let "a=2*num"
????if [ $a -eq $sum ]
????then
????????echo $num
????fi
}
num=1
while [ $num -le 1000 ]
do
????sub
????let "num = num+1"
done
11.以行為單位,求文件A和文件B交集,并集,差集。
并:
sort -m <(sort A | uniq) <(sort B | uniq) | uniq
交:
sort -m <(sort A | uniq) <(sort B | uniq) | uniq -d
差:
sort -m <(sort A | uniq) <(sort B | uniq) <(sort B | uniq) | uniq -u
12.在某個文件夾下查找含有指定字符串的文件
#!/bin/bash
for file in $(ls $2)
do
????bname=$(grep -l $1 $2/$file)
????basename $bname
done
調用方法:./tst 000 bash#在文件夾bash中查找含有“000”的文件。
13.添加一個新組為class1,然后添加屬于這個組的30個用戶,用戶名的形式為stdxx,其中xx從01到30。
#!/bin/bash
groupadd class1
for i in {9901..9930}
do
????xx=$(echo $i | sed 's/99//');
????useradd -g class1 std$xx -p ""
done
14.實現自動刪除50個賬號的功能。賬號名為stud1至stud50
#!/bin/bash
i=0
while [ i -le 50 ]
do
???let i++
???????userdel -r stud$i
done
15.某系統管理員需每天做一定的重復工作,請按照下列要求,編制一個解決方案:
(1)在下午4 :50刪除/abc目錄下的全部子目錄和全部文件;
(2)從早8:00~下午6:00每小時讀取/xyz目錄下x1文件中每行第一個域的全部數據加入到/backup目錄下的bak01.txt文件內;
(3)每逢星期一下午5:50將/data目錄下的所有目錄和文件歸檔并壓縮為文件:backup.tar.gz;
(4)在下午5:55將IDE接口的CD-ROM卸載(假設:CD-ROM的設備名為hdc);
(5)在早晨8:00前開機后啟動。
vim /etc/crontab 在里面增加下面內容:
1)50 16 * * * root rm -rf /abc/* 2>&1 &
2)00 8-18 * * * root cat /xyz/x1|awk '{print $1}' >> /backup/bak01.txt 2>&1 &
3)50 17 * * 1 root cd /data;tar -zcvf backup.tar.gz * 2>&1 &
4)55 17 * * * root umount /hdc 2>&1 &
5)在早晨8:00前開機后啟動 --> 這個我不是很明白它的意思,不知道是不是8點前開機就啟動上面的設定,8點后才開機就不用啟動的意思。姑且用下面這個命令吧。
chkconfig --level 2345 crond on
16.設計一個shell程序,在每月第一天備份并壓縮/etc目錄的所有內容,存放在/root/bak目錄里,且文件名
為如下形式yymmdd_etc,yy為年,mm為月,dd為日。Shell程序fileback存放在/usr/bin目錄下。
vim /usr/bin/fileback.sh
#!/bin/bash
#fileback.sh
#file executable: chmod 755 fileback.sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
filename=`date +%y%m%d`_etc.tar.gz
cd /etc/
tar -zcvf $filename *
mv $filename /root/bak/
------------------------------------------------------
vim /etc/crontab 加入
* * 1 * * root ./fileback.sh &
17.有一普通用戶想在每周日凌晨零點零分定期備份/user/backup到/tmp目錄下,該用戶應如何做?
首先說一下非root用戶編寫crontab文件的方法。
一:
[sword@localhost ~]$ vim cronfile
[sword@localhost ~]$ crontab cronfile
二:
[sword@localhost ~]$ crontab -e
no crontab for sword - using an empty one
crontab: installing new crontab
查看結果:
[root@localhost cron]# crontab -u sword -l
顯示內容是:/var/spool/cron/sword 文件的內容。
vim ~/shit.sh
#!/bin/bash
cp /user/backup/* /tmp/
--------------------------------------------
crontab -e
0 0 * * 0 ~/shit.sh &
18.設計一個Shell程序,在/userdata目錄下建立50個目錄,即user1~user50,并設置每個目錄的權限,其
中其他用戶的權限為:讀;文件所有者的權限為:讀、寫、執行;文件所有者所在組的權限為:讀、執行。
#!/bin/bash
for ((i=1;i<=50;i++))
do
???????mkdir -p /usrdata/user$i
???????cd /usrdata
???????chmod 754 user$i
done
19.一個文件內容全部是類似
【202.205.151.21】--【23:59:22】-“HTTP GET”-“Mozila”
...
寫一個SHELL命令找出最多的10個IP
awk -F "--" '{print $1}' shit | sort | uniq -c | sort -r | sed -n '1,10p'
20./tmp路徑下有800個文件,文件名的格式是:filename_YYYYMMDD_序列號(從001到999).dat, 例如:filename_20040108_089.dat。現在想把這些文件改名,新文件名的格式是:filename_TODAY(當前日期)_序列號(從500開始,到達999之后從001開始).dat,例如: 把filename_20040108_089.dat改為filename_20041222_589.dat,注意新文件名的序列號的順序需要和原來的一致,即要做排序處理。
#!/usr/bin/bash
DEST_FILE_PART2="_`date '+%Y%m%d'`_"
EXT_NAME=".dat"
SRC_FILE_LIST=`find /tmp -name "*_*_*$EXT_NAME" -print`
for each in $SRC_FILE_LIST; do
????DEST_FILE_PART1=`echo $each | awk -F"_" '{print $1}'`
????OLD_NUM=`echo $each | awk -F"_" '{print $3}' | awk -F"." '{print $1}'`
????DEST_FILE_PART3=`expr $OLD_NUM + 500`
????[ $DEST_FILE_PART3 -gt 999 ] && DEST_FILE_PART3=`expr $OLD_NUM - 499`
????????&& DEST_FILE_PART3=`printf d $DEST_FILE_PART3`
????DEST_FILE=$DEST_FILE_PART1$DEST_FILE_PART2$DEST_FILE_PART3$EXT_NAME
????echo "mv $each to $DEST_FILE"
????mv $each $DEST_FILE
done
我的解法:
#!/bin/bash
new_file=$(date +20%y%m%d);
for file in $(ls ~/bash)
do
????i=$(echo "$file" | sed 's/.*_[0-9]*_\([0-9]*\).dat/\1/')????#取出序列號
????i=$(echo $i | sed 's/^0*\([0-9]*\)/\1/')????????????????#去掉序列號前面可能的 ‘0’,
????let "ii=i+500"
????if [ $ii -gt 999 ]
????then
????????let "ii=ii-999"
????fi
????ii=`printf d $ii`????????????????????????????#添上可能需要的‘0’
????update=$(echo "$file" | sed 's/\(.*\)_[0-9]*_[0-9]*.dat/\1_'$new_file'_'$ii'.dat/')
????mv ~/bash/$file ~/bash/$update
done
21.要求:在一個腳本中完成這個程序
1.從文件user.list中取出已給定的用戶名和用戶組,將這些用戶和組按規則添加到系統中
2.從password.list中讀取已經給定的用戶密碼。
user.list如下
zhangsan adminuser,dbuser,updatauser
lisi dbuser,updatauser
wanger updatauser,wheel
#!/bin/bash
#group add
for x in ‘awk ‘{print $2}’ user.list | sed ’s/,/\n/g’ | sort | uniq -c|sed ’s/[^a-zA-Z]//g”
do
????????groupadd $x &> /dev/null
done
#back message
if (($?==0))
then
????????echo “Group Ok!!”
else
????exit 1
fi
#user add
for i in ‘awk ‘{print $1}’ user.list’
do
????for y in ‘awk ‘{print $2}’ password.list’
????do
????useradd $i &> /dev/null
????echo $y | passwd –stdin $i &> /dev/null
????done
done
#back message
if (($?==0))
then
????echo “User Ok!”
else
????exit 1
fi
#add users to groups
for ((q=1;q<=3;q++))
do
????usermod -G ‘awk “NR==$q {print $2}” user.list | awk ‘{print $2}” ‘awk “NR==$q {print $1}” user.list | awk ‘{print $1}” &> /dev/null
done
if (($?==0))
then
????echo “All Finished!”
fi
22.比較兩個小數大小。
awk -v num1=6.6 -v num2=5.5 'BEGIN{print(num1>num2)?"0":"1"}'
echo "0.14 > 0.15" | bc
expr 1.2 \< 1.3
??
24. Shell腳本閱讀(解釋下面執行的功能),請挑出下面程序或腳本中的錯誤,并說明錯在哪里。
#!/bin/bash
#監控cpuser的point端口是否正常
logname="/home/forum/log/lpointlog.wf"
flagfile="/home/forum/log/lognum.txt"
lodnum=sed -n "1,1 p"$flagfile
newnum=wc -l ${logname}
echo $newnum >$flagfile
totalnum=expr $newnum -$oldnum
tail -n $totalnum $logname |grep "POINT_THREAD WARNING"
if [$?==0]
then
???mail -s "cpuser point "端口異常,請處理!"?test@aa.com</dev/null
fi>
?
命令行替換用反引號,if [$?==0] 應該寫做if [ $?=0 ],用來判斷上次命令是否執行成功;
倒數第二行應該是>/dev/null,最后fi后面的>去掉。
?
25. 設計一個shell程序,在每月第一天備份并壓縮/etc目錄的所有內容,存放在/root/bak目錄里,且文件名為如下形式yymmdd_etc,yy為年,mm為月,dd為日。Shell程序fileback存放在/usr/bin目錄下。
參考答案:
(1)編寫shell程序fileback:
#!/bin/sh
DIRNAME=`ls /root | grep bak`
if [ -z "$DIRNAME" ] ; then
mkdir /root/bak
cd /root/bak
fi
YY=`date +%y`
MM=`date +%m`
DD=`date +%d`
BACKETC=$YY$MM$DD_etc.tar.gz
tar zcvf $BACKETC /etc
echo "fileback finished!"
(2)編寫任務定時器:
echo "0 0 1 * * /bin/sh /usr/bin/fileback" >; /root/etcbakcron
crontab /root/etcbakcron
或使用crontab -e 命令添加定時任務:
0 1 * * * /bin/sh /usr/bin/fileback
26. 有10臺被監控主機,一臺監控機,在監控機上編寫腳本,一旦某臺監控機器/分區使用率大于80%,就發出報警,放到crontab里面,每10分鐘檢查一次。
(1)首先,建立信任關系 1 VS 10. 但拿兩臺機器(192.168.1.6,192.168.1.4)做試驗
#ssh-keggen -b 1024 -t rsa??//(以root用戶)
#cd .ssh/
#ls
id_rsa
id_rsa.pub
knows_host
#scp id_rsa.pub 192.168.1.4:/root/.ssh/192.168.1.6
這里把公鑰取名為可信任主機的IP地址
現在登錄到192.168.1.4機器
#cd .ssh/
#cat 192.168.1.6 >> authorized_keys
然后回到192.168.1.6機器。
#ssh 192.168.1.4
這樣就可以了,里面可能涉及到權限問題。一般.ssh/文件夾為755,authorized_keys 600或644
(2)腳本如下:
#!/bin/sh
#script:df_check.sh
FSMAX="80"
remote_user='root'
remote_ip=(192.168.1.2 192.168.1.3 192.168.1.4 .......)???//十個ip地址
ip_num='0'
while [ "$ip_num" -le "$(expr ${#remote_ip[@]} - 1)" ]
do
read_num='1'
ssh?"$remote_user"@"${remote_ip[$ip_num]}" df -h >/tmp/diskcheck_tmp
grep '^/dev/*' /tmp/diskcheck_tmp|awk '{print $5}'|sed 's/\%//g' >
/tmp/diskcheck_tmp_num
while [ "$read_num" -le $(wc -l < /tmp/diskcheck_tmp_num)] //計算有多少行
do
size=$(sed -n "$read_num"'p' /tmp/diskcheck_tmp_num)
if [ "$size" -gt "$FSMAX" ]
then
$(grep '^/dev/*' /tmp/diskcheck_tmp|sed -n $read_num'p' >
/tmp/disk_mail)
$(echo $(remote_ip[$ip_num]) >> /tmp/disk_mail)
$(mail -s "diskcheck_alert" admin </tmp/disk_mail)
fi
read_num=$(expr $read_num + 1)
done
ip_num=$(expr $ip_num + 1)
done
(3)放在crontab里面
#######################################################################
################讓腳本每十分鐘執行一次#################################
在cron表中:
0/10 * * * * /home/codefei/diskcheck.sh 2>&1
?
27. 用Shell編程,判斷一文件是不是字符設備文件,如果是將其拷貝到 /dev 目錄下。
參考程序:
#!/bin/sh
FILENAME=
echo “Input file name:”
read FILENAME
if [ -c "$FILENAME" ]
then
cp $FILENAME /dev
fi
總結
- 上一篇: 某linux主机的/etc/rc.d/r
- 下一篇: shell编程中crontab用法超级详