shell 筆試題

sgy618發表於2011-06-07

shell 筆試題

[@more@]

hell 例項
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" < ~/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=
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 -m 差:
sort -m

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前開機後啟動 --&gt 這個我不是很明白它的意思,不知道是不是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 %03d $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 %03d $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

2.建立組帳戶class1,並新增30個屬 於這個組的使用者,使用者名稱為stdxx,其中xx為01到30.
[root@test ~]# cat abc
#!/bin/sh
groupadd class1
a=1
while [ $a -le 30 ]
do
if [ $a -le 9 ]; then
username=stu0$a
else
username=stu$a
fi
a=`expr $a + 1`
useradd -g class1 $username
done

3.刪除組帳戶class1,並刪除其下的 30個使用者
[root@test ~]# cat ggg
#!/bin/sh
a=1
while [ $a -le 30 ]
do
if [ $a -le 9 ]; then
username=stu0$a
else
username=stu$a
fi
a=`expr $a + 1`
userdel $username
done
groupdel class1


利用top取某個程式的CPU的指令碼:


#/bin/sh

Max_CPU=0
Avg_CPU=0
Total_Time=1

Process=$1
Interval=$2

# check the parameters
if [ $# -ne 2 ]; then
echo "Usage: $0 ProcessName Interval"
exit
fi

LogFile="Per.txt"
echo "`date`" > $LogFile

while sleep $Interval
do
top -d 1 -n 1|grep $Process|grep -v grep|awk '{print $9"t"$10}' >> $LogFile
done

判斷是否是裝置檔案

#/bin/bash

echo -e "The program will Judge a file is or not a device file.nn"

read -p "Input a filename:" filename

if [ -b $filename -o -c $filename ]; then

echo "$filename is a device file"

exit 0

else

echo "$filename is not a device file"

exit 1

firead –p:用於在讀資料時輸出提示資訊

注意! [ 之間是有空格的:if ! [ -f $filename ] ; then。一般用if [ ! * ]

新增使用者:

#/bin/bash

groupadd -f class1

for i in {9909..9911}

do

xx=`echo $i | sed 's/99//g'`

useradd -g class1 std${xx}

echo std${xx} | passwd std${xx} --stdin

echo -e "user std${xx} passwd is std${xx}">>/root/newuser.txt

done

exit 0

注意等號的前後不要有空格:xx=`echo $i | sed 's/99//g'`

變數如果前後有字元,要是大括號

統計IP訪問:
要求分析apache訪問日誌,找出訪問頁面數量在前100位的IP數。日誌大小在78M左右。以下是apache的訪問日誌節選

202.101.129.218 - - [26/Mar/2006:23:59:55 +0800] "GET /online/stat_inst.php?pid=d065 HTTP/1.1" 302 20-"-" "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"

# awk '{print $1}' log |sort |uniq -c|sort -r |head -n10

5 221.224.78.15

3 221.233.19.137

1 58.63.148.135

1 222.90.66.142

1 222.218.90.239

1 222.182.95.155

1 221.7.249.206

1 221.237.232.191

1 221.235.61.109

1 219.129.183.122

求2個數之和
#/bin/bash

typeset first second

read -p "Input the first number:" first

read -p "Input the second number:" second

result=$[$first+$second]

echo "result is : $result"

exit 0

文字分析
取出password中shell出現的次數
第一種方法結果:
4 /bin/bash
1 /bin/sync
1 /sbin/halt
31 /sbin/nologin
1 /sbin/shutdown
第二種方法結果:
/bin/sync 1
/bin/bash 1
/sbin/nologin 30
/sbin/halt 1
/sbin/shutdown 1

答案:

cat /etc/passwd|awk -F: '{if ($7!="") print $7}'|sort|uniq –c

cat /etc/passwd|awk -F: '{if ($7!="") print $7}'|sort|uniq -c | awk '{print $2,$1}'

檔案整理
employee檔案中記錄了工號和姓名
employee.txt:
100 Jason Smith
200 John Doe
300 Sanjay Gupta
400 Ashok Sharma
bonus檔案中記錄工號和工資
bonus.txt:
100 $5,000
200 $500
300 $3,000
400 $1,250
要求把兩個檔案合併並輸出如下
處理結果:
400 ashok sharma $1,250
100 jason smith $5,000
200 john doe $500
300 sanjay gupta $3,000

答案:join employee bonus | sort -k 2

列印本機的交換分割槽大小
處理結果:
Swap:1024M

free -m | sed -n '/Swap/p' | awk '{ print $2}'

free -m | sed -n 's/Swap: *([0-9]*).*/1/p'

輸出本機建立20000個目錄所用的時間
處理結果:
real 0m3.367s
user 0m0.066s
sys 0m1.925s

答案:

# time for i in {1..2000} ; do mkdir /root/neil$i; done

real 0m6.200s

user 0m1.128s

sys 0m4.710s

列印當前sshd的埠和程式id
處理結果:
sshd Port&&pid: 22 5412

答案:netstat -anp | grep sshd | sed -n 's/.*:::([0-9]*) .* ([0-9]*)/sshd/1 2/p'

列印root可以使用可執行檔案數
處理結果:
root's bins: 2306

echo "root's bins: $(find ./ -type f | xargs ls -l | sed '/-..x/p' | wc -l)"

root's bins: 3664

編譯當前目錄下的所有.c檔案:

for file in *.c; do echo $file ; gcc -o $(basename $file .c) $file ; sleep 2; done > compile 2>&1

將一目錄下所有的檔案的副檔名改為bak
for i in *.*;do mv $i ${i%%.*}.bak;done

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23168012/viewspace-1050887/,如需轉載,請註明出處,否則將追究法律責任。

相關文章