例題一:編寫腳本/root/bin/createuser.sh,實現以下功能:linux
使用一個用戶名作爲參數,若是指定參數的用戶存在,就顯示其存在,不然添加之;並生成8位隨機口令並存在一個文件中,初步提示改口令,顯示添加的用戶的id號等信息centos
#!/bin/bash # ------------------------------------------ # Filename: useradd.sh # Revision: null # Date: 2017-09-11 21:47:22 # Author: 趙東 # Email: 1213217229@qq.com # Website: null # Description: new file # ------------------------------------------ for i in {1..10};do pw=`cat /dev/urandom |tr -dc [[:alnum:][:graph:]]|head -c 8` #生成8位隨機字符密碼 useradd user$i &> /dev/null if [ $? -eq 0 ];then echo $pw | passwd --stdin user$i &> /dev/null echo "user user$i password is $pw" else echo "user$i already exist" fi done #for i in {1..10};do userdel -r user$i;done 刪除生成的用戶
本題重點:bash
①生成指定長度的隨機數dom
cat /dev/urandom |tr -dc [[:alnum:][:graph:]]|head -c 8ide
/dev/urandom中包含了無數個隨機字符,經常使用於隨機數的生成,這裏咱們只須要保留其中的英文和數字,從而截取前8個字符函數
②從標準輸入設置用戶密碼ui
echo string | passwd --stdin username &> /dev/nullspa
例題二:編寫腳本/root/bin/checkint.sh,判斷用戶輸入的參數是否爲正整數rest
#!/bin/bash # ------------------------------------------ # Filename: checkint.sh # Revision: null # Date: 2017-09-11 20:54:50 # Author: 趙東 # Email: 1213217229@qq.com # Website: null # Description: new file # ------------------------------------------ read -p "Please input a number: " num if [[ $num =~ ^[1-9]+[0-9]*$ ]];then echo "true" else echo "false";exit 20 fi
本題重點:ip
而事實上,正整數只是不包括負號‘-’小數點‘.’且開頭不爲0的數字的集合,這樣想起來就很容易表達了,因此正整數的表達方式以下
[[ $num =~ ^[1-9]+[0-9]*$ ]]
例題三:/etc/rc.d/rc3.d目錄下分別有多個以K開頭和以S開頭的文件;分別讀取每一個文件,以K開頭的輸出爲文件加stop,以S開頭的輸出爲文件名加start,如K34filename stop
#!/bin/bash # ------------------------------------------ # Filename: startorstop.sh # Revision: null # Date: 2017-09-12 08:43:15 # Author: 趙東 # Email: 1213217229@qq.com # Website: null # Description: new file # ------------------------------------------ ls /etc/rc.d/rc3.d/ | while read filename;do case $filename in K*) echo "$filename start" ;; S*) echo "$filename stop" ;; esac done
本題重點:
①while的特殊用法:以行爲單位遍歷文件內容和遍歷指定目錄下的文件名
用法一: 遍歷文件內容
while read line;do
循環體
done < 文件路徑
其中line爲自定義變量,表示文件的行
用法二:配合管道進行遍歷,管道前可接命令,若是有多個命令,則用「;」隔開(超好用!!)
ls /path/dirname | while read filename;do
循環體
done
②case判斷語句中的判斷條件支持glob風格的通配符,例如如下經常使用幾種:
*:任意長度字符
?:任意單個字符
[]:任意範圍內的單個字符
a|b:a或b
例題四:打印九九乘法表
#!/bin/bash # ------------------------------------------ # Filename: 99.sh # Revision: null # Date: 2017-08-25 00:49:26 # Author: zhaodong # Email: 1213217229@qq.com # Website: null # Description: new file # ------------------------------------------ echo "99乘法表" for i in `seq 1 9`;do for j in `seq 1 $i`;do echo -en "${i}X${j}=$[$i*$j]\t" done echo done
本題重點:
如何輸出指定範圍內的數字或字母???
狀況一:沒有引用變量
{1..100} {a..z}
狀況二:引用變量值
`seq 1 $num` `seq a $alpha` ( 注意:seq 是一個命令,因此引用命令結果須要加``或$() )
例題五:
後續六個字符串:efbaf275cd、4be9c40b8b、44b2395c4六、f8c8873ce0、b902c16c8b、ad865d2f63是經過對隨機數變量RANDOM隨機執行命令:
echo $RANDOM|md5sum|cut –c1-10後的結果,請破解這些字符串對應的RANDOM值
#!/bin/bash # ------------------------------------------ # Filename: md5.sh # Revision: null # Date: 2017-09-12 21:15:21 # Author: 趙東 # Email: 1213217229@qq.com # Website: null # Description: new file # ------------------------------------------ read -p "Please input your passwd: " md5_pwd i=1 while [ $i -le 60000 ];do #窮舉60000次 rdm_num=$RANDOM a=`echo ${rdm_num}|md5sum|cut -c1-10` if [ $a == $md5_pwd ];then result=`echo $rdm_num` break else let i++ continue fi done echo "result= " $result unset i md5_pwd
例題六:
編寫服務腳本/root/bin/testsrv.sh,完成以下要求
(1) 腳本可接受參數:start, stop, restart, status
(2) 若是參數非此四者之一,提示使用格式後報錯退出
(3) 如是start:則建立/var/lock/subsys/SCRIPT_NAME, 並顯示「啓動成功」
考慮:若是事先已經啓動過一次,該如何處理?
(4) 如是stop:則刪除/var/lock/subsys/SCRIPT_NAME, 並顯示「中止完成」
考慮:若是事先已然中止過了,該如何處理?
(5) 如是restart,則先stop, 再start
考慮:若是原本沒有start,如何處理?
(6) 如是status, 則若是/var/lock/subsys/SCRIPT_NAME文件存在,則顯示「SCRIPT_NAMEis running...」
若是/var/lock/subsys/SCRIPT_NAME文件不存在,則顯示「SCRIPT_NAME is stopped...」
其中:SCRIPT_NAME爲當前腳本名
#!/bin/bash # ------------------------------------------ # Filename: testsrv.sh # Revision: null # Date: 2017-09-13 22:12:10 # Author: 趙東 # Email: 1213217229@qq.com # Website: null # Description: new file # ------------------------------------------ . /etc/init.d/functions #調用函數 filename=`echo /var/lock/subsys/testsrv.sh` #設置文件名 ls $filename &> /dev/null && exist=true || exist=false #檢查文件是否存在 if [ $# -eq 1 ];then #判斷位置參數是否爲一個 if [ "$1" == "start" ]||[ "$1" == "stop" ]||[ "$1" == "restart" ]||[ "$1" == "status" ];then #判斷位置參數的值 case $1 in start) if [ "$exist" == "false" ];then touch $filename action "successfull start it" true elif [ "$exist" == "true" ];then action "Already running..." false fi ;; stop) if [ "$exist" == "true" ];then rm -rf $filename action "successfull stop it" true elif [ "$exist" == "false" ];then action "failed stop it" false fi ;; restart) if [ "$exist" == "false" ];then action "Stopping it:" false touch $filename echo "starting..." action "Restart successfull" true elif [ "$exist" == "true" ];then rm -rf $filename echo "stopping..." touch $filename echo "starting..." action "Restart successfull" true fi ;; status) if [ "$exist" == "true" ];then echo "`basename $filename` is running..." elif [ "$exist" == "false" ];then echo "`basename $filename` is stopped..." fi esac else echo "usage: `basename $filename` {start|stop|restart|status} " exit 1 fi else echo "Useage is: `basename $filename` {arg} " exit 2 fi
本題重點:
函數的調用
當在腳本中引用函數文件中的函數時,正確步驟以下:
步驟1: . /source 函數文件名 f-----執行函數文件(之因此使用這種方式是爲了不進入二級bash從而影響變量的使用)
步驟2: 函數名 -----調用函數
例題七:
編寫腳本/root/bin/copycmd.sh
(1) 提示用戶輸入一個可執行命令名稱
(2) 獲取此命令所依賴到的全部庫文件列表
(3) 複製命令至某目標目錄(例如/mnt/sysroot)下的對應路徑下;如:/bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd==> /mnt/sysroot/usr/bin/passwd
(4) 複製此命令依賴到的全部庫文件至目標目錄下的對應路徑下:如:/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
(5)每次複製完成一個命令後,不要退出,而是提示用戶鍵入新的要複製的命令,並重復完成上述功能;直到用戶輸入quit退出
#!/bin/bash # ------------------------------------------ # Filename: copycmd.sh # Revision: null # Date: 2017-09-14 20:04:12 # Author: 趙東 # Email: 1213217229@qq.com # Website: null # Description: new file # ------------------------------------------ while true;do read -p "Please Input a command(Input "q" or "quit" can be quit): " com command_exist=`which $com &> /dev/null;echo $?` #判斷命令是否存在的變量,存在爲0 if [ "$com" == "q" ]||[ "$com" == "quit" ] ;then #1.判斷是否用戶是否想退出 break elif [ `echo $command_exist` != 0 ];then #2.判斷命令是否存在 echo -e "\033[1;31mCommand $com unexist\033[0m" continue else binary=`which $com | tail -1` #二進制文件路徑 libfile=`ldd $binary | cut -d'>' -f2|grep /|cut -d'(' -f1` #全部庫文件 路徑 dirname=/mnt/sysroot`dirname $binary` #二進制文件目標目錄 echo -e "\033[1;32m1.The list of "$com" dependence lib files is:\033[0m" echo "$libfile" #3.顯示全部庫文件 if [ -e /mnt/sysroot$binary ];then #4.判斷二進制文件是否已拷貝 echo -e "\033[1;31mCommand already copied\033[0m" else mkdir -p $dirname cp -a $binary $dirname #5.複製二進制文件到目標目錄 echo -e "\033[1;32m2.Binary files copy successfull\033[0m\n$binary===========>/mnt/sysroot$binary" echo -e "\033[1;32m3.Copying lib files:\033[0m" for i in `echo $libfile`;do #5.遍歷庫文件,並依次複製庫文件 mkdir -p /mnt/sysroot`dirname $i` #建立新的庫目錄 cp -a $i /mnt/sysroot`dirname $i` echo -e "$i===========>/mnt/sysroot${i}\n" done echo -e "\033[1;32mLib files copy successfull\033[0m" fi fi done
本體重點:
①顯示指定命令的二進制文件
which command | tail -1 爲啥要截最後一行呢??由於命令可能存在別名,好比下邊這種狀況
[root@centos6 ~]# which ls alias ls='ls --color=auto' /bin/ls
②截取指定命令的全部庫文件
ldd `which command | tail -1 ` | cut -d'>' -f2|grep /|cut -d'(' -f1