shell 實例收集

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" [email protected] < ~/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 "端口異常,請處理!" [email protected]</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

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章