文法格式:
逐條件進行判斷,第一次遇為“真”條件時,執行其分支,而後結束整個if語句
示例
判斷分數
适合判斷離散值,比如,1,3,9
可以有多種格式
case支援glob風格的通配符:
[ ] *: 任意長度任意字元
[ ] ?: 任意單個字元
[ ] []:指定範圍内的任意單個字元
[ ] a|b: a或b
練習
1、編寫腳本createuser.sh,實作如下功能:使
用一個使用者名做為參數,如果指定參數的使用者存在,就顯示其存在,否則添加之;顯示添加的使用者的id号等資訊
2、編寫腳本yesorno.sh,提示使用者輸入yes或no,
并判斷使用者輸入的是yes還是no,或是其它資訊
3、編寫腳本filetype.sh,判斷使用者輸入檔案路徑
顯示其檔案類型(普通檔案,目錄,連結,其它檔案類型)
[ -L $path] 是判斷:存在且為符号連結檔案,判斷的結果是以連結檔案背後的指向為準,也就是說,如果符号連結實際指向的一個目錄的話,這具判斷的結果就是一個目錄,而不是本身符号連結
是以上面的例子使用的是file來判斷。
比如這個檔案:
4、編寫腳本checkint.sh,判斷使用者輸入的參數是否為正整數
上面的例子用到了正規表達式,注意了 =~ 右邊不允許出現引号。echo -e 是啟用後面的顔色轉義。
循環執行
将某代碼段重複運作多次
重複運作多少次:
[ ] 循環次數事先已知
[ ] 循環次數事先未知
有進入條件和退出條件
第一種
[x] 執行機制:
依次将清單中的元素指派給“變量名” ; 每次指派後即執行一次循環體; 直到清單中的元素耗盡,循環結束。
清單生成方式:
[ ] (1) 直接給出清單
如:for i in 1 2 3
[ ] (2) 整數清單:
[ ] (a) {start..end}
如:for i in {a..z}
[ ] (b) $(seq [start [step]] end)
如:for i in $(seq 1 2 10)
[ ] (3) 傳回清單的指令$(COMMAND)
如:for i in $(seq 1 10)
[ ] (4) 使用通配符
如:for i in /app/shell/*.sh
[ ] (5) 變量引用;$@, $*
如:for i in $@
把1-100相加的結果顯示出來
文法格式:(第二種) C語言風格
運作結果
#!/bin/bash
for i in {1..100};do
if [ "$[i%3]" -ne 0 ];then
echo -n "$i "
let sum+=i
fi
done
echo -e "\n100以内不能被3整除的數相加的結果是:$sum"
1 2 4 5 7 8 10 11 13 14 16 17 19 20 22 23 25 26 28 29 31 32 34 35 37 38 40 41 43 44 46 47 49 50 52
53 55 56 58 59 61 62 64 65 67 68 70 71 73 74 76 77 79 80 82 83 85 86 88 89 91 92 94 95 97 98 100
100以内不能被3整除的數相加的結果是:3367
_path=/var/*
for i in $_path;do
echo "$i的檔案類型是:<code>stat -c %F $i</code>"
#bash checkfile.sh
/var/adm的檔案類型是:directory
/var/cache的檔案類型是:directory
/var/crash的檔案類型是:directory
/var/db的檔案類型是:directory
/var/empty的檔案類型是:directory
/var/games的檔案類型是:directory
/var/gopher的檔案類型是:directory
/var/kerberos的檔案類型是:directory
/var/lib的檔案類型是:directory
/var/local的檔案類型是:directory
/var/lock的檔案類型是:symbolic link
/var/log的檔案類型是:directory
/var/mail的檔案類型是:symbolic link
/var/nis的檔案類型是:directory
/var/opt的檔案類型是:directory
/var/preserve的檔案類型是:directory
/var/run的檔案類型是:symbolic link
/var/spool的檔案類型是:directory
/var/tmp的檔案類型是:directory
/var/www的檔案類型是:directory
/var/yp的檔案類型是:directory
stat -c 後面可以按指定格式輸出檔案屬性資訊
以下方法都可以取随機數,請參考:
#cat /dev/urandom |tr -dc 'a-zA-Z0-9'|head -c8
#openssl rand -base64 10|head -c8
#定義了記錄密碼檔案的變量
_passwdfile=/app/passwd.txt
for i in {1..10};do
#建立使用者并将建立的使用者名寫入指定檔案
useradd user$i
echo -n "user$i:" >> $_passwdfile
#算出随機數并交給passwd更新使用者密碼
echo "<code>openssl rand -base64 10|head -c8</code>" | tee -a $_passwdfile | passwd --stdin user$i &> /dev/null
echo "使用者user$i建立完畢,并設定了随機8位密碼,密碼記錄在:$_passwdfile"
#cat /app/passwd.txt
user1:y70D9Jp7
user2:Ykseahss
user3:pSFLZ5bP
user4:9NNjOy4M
user5:LSiIB8IX
user6:0aGjxkWN
user7:pAvtRQkT
user8:GimQuuYN
user9:yR4YJR+U
user10:BxzFRlSW
tee指令用于将上一條指令的stdout重定向到檔案,并且重定向副本作為後續指令的stdin
-a:向檔案中重定向時使用追加模式,相當于重定向的 >>
#使用if的方法
_path=/etc/rc.d/rc3.d/
if [[ <code>basename $i</code> =~ ^K. ]];then
echo "$i stop"
elif [[ <code>basename $i</code> =~ ^S.* ]];then
echo "$i start"
#使用case的方法
case <code>basename $i</code> in
K)
echo "<code>basename $i</code> stop"
;;
S*)
echo "<code>basename $i</code> start"
esac
#bash checkrcd.sh
/etc/rc.d/rc3.d/K50netconsole stop
/etc/rc.d/rc3.d/S10network start
#判斷使用者輸入的是否正整數
read -p "請輸入正整數num的值,腳本将會計算從1到num的總和并顯示: " num
if [[ ! $num =~ ^[1-9][0-9]*$ ]];then
echo "輸入的不是正整數,正整數的範圍是1-∞,腳本将會退出"
exit 10
else
unset sum
for i in <code>seq 1 "$num"</code>;do
let sum+=$i
echo "從1到num的總和 是:$sum"
#定義了IP位址中,網絡位址的格式,如 192.168.0
regex='\<(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>'
#定義線上主機存放檔案
_onlineip=/app/online_ip.txt
#定義不線上主機存放檔案
_offlineip=/app/offline_ip.txt
#每次掃描前清空上次存放的記錄
$_onlineip $_offlineip read -p "請輸入要掃描的網絡位址,如 192.168.0 " ipnet #判斷輸入的網絡位址是否合法 if [[ ! "$ipnet" =~ $regex ]];then echo "輸入的網絡位址不合法,腳本将退出" for i in {1..254};do #這裡使用{ }是為了并行處理,提高效率 { if ping -c 2 -w 2 $ipnet.$i &> /dev/null;then echo "IP $ipnet.$i 線上" echo "$ipnet.$i" >> $_onlineip echo "IP $ipnet.$i 不線上" echo "$ipnet.$i" >> $_offlineip } & wait
#bash scanip.sh 請輸入要掃描的網絡位址,如 192.168.0 192.168.4 IP 192.168.4.1 線上 IP 192.168.4.100 線上 IP 192.168.4.101 線上 IP 192.168.4.53 不線上 IP 192.168.4.31 不線上 IP 192.168.4.128 不線上 如果不用并發處理,看到的順序會從1~254,不過就太慢了。 wait指令可以讓背景執行程式執行完成後退出
_line=4
_colum=8
for i in <code>seq $_line</code>;do
for j in <code>seq $_colum</code>;do
echo -n "*"
echo
#bash juxing.sh
文法1:
#/bin/bash
#循環行數
for i in {1..9};do
#循環列的數量,等于行數
for j in <code>seq $i</code>;do
echo -ne "$j X $i = $[j*i]\t"
#輸出一個新行,便于每一行之後換行
#bash 99.sh
1 X 1 = 1
1 X 2 = 2 2 X 2 = 4
1 X 3 = 3 2 X 3 = 6 3 X 3 = 9
1 X 4 = 4 2 X 4 = 8 3 X 4 = 12 4 X 4 = 16
1 X 5 = 5 2 X 5 = 10 3 X 5 = 15 4 X 5 = 20 5 X 5 = 25
1 X 6 = 6 2 X 6 = 12 3 X 6 = 18 4 X 6 = 24 5 X 6 = 30 6 X 6 = 36
1 X 7 = 7 2 X 7 = 14 3 X 7 = 21 4 X 7 = 28 5 X 7 = 35 6 X 7 = 42 7 X 7 = 49
1 X 8 = 8 2 X 8 = 16 3 X 8 = 24 4 X 8 = 32 5 X 8 = 40 6 X 8 = 48 7 X 8 = 56 8 X 8 = 64
1 X 9 = 9 2 X 9 = 18 3 X 9 = 27 4 X 9 = 36 5 X 9 = 45 6 X 9 = 54 7 X 9 = 63 8 X 9 = 72 9 X 9 = 81
文法2:
for (( i=1;i<=9;i++ ));do
for (( j=1;j<=i;j++ ));do
echo -ne "${j}x${i}=$[j*i]\t"
#bash 99-new.sh
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12 4x4=16
1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81
echo " 建立了 <code>mktemp --suffix=.html -p /tmp/ ${i}XXXXXXXX</code>"
#ls /tmp/
1tKMzfFfVx.html 2GvLrwZHn.html 4ms1ildS9.html 6ZwlWhu02.html 8k49voEHW.html
10FJDRpge.html 3khkjI5vu.html 5uOIumnYP.html 7pYy7KHuN.html 9QDJaNxg2.html
mktemp用于生成指定數量的随機臨時檔案。XXX是指定具體數量的随機符号,3個XXX就是3個,
--suffix=.html,用于指定字尾。
-p 用于指定目錄
#使用openssl rand 生成随機數方法
touch /tmp/$i<code>openssl rand -base64 12|tr -dc '[:alnum:]'|head -c8</code>.html
#使用cat /dev/urandom生成随機數方法
touch /tmp/$i<code>cat /dev/urandom|tr -dc '[:alnum:]'|head -c8</code>.html
至于效率哪個高,請使用time 腳本進行測試吧,工作中按需使用。
要點:
先打空格,再打星星
每行列印的空格數=總行數-目前行數
每行列印的星星數=目前行數 X 2 -1
read -p "請輸入總的行數:" topline
if [[ ! "$topline" =~ ^[1-9][0-9]$ ]];then
echo "你輸入的不是正整數"
#循環總數
for i in <code>seq $topline</code>;do
#每行列印的空格數=總行數-目前行數
for j in <code>seq $[$topline-$i]</code>;do
echo -n " "
#每行列印的星星數=目前行數x2-1
for k in `seq $[$i2-1]`;do
#列印換行,進行下一輪循環
#bash sanjiao.sh
請輸入總的行數:5
*
#定義外層星星顔色
_color1="\033[1;5;$[$RANDOM%7+31]m"
_color2="\033[0m"
#定義内層星星顔色
_colorstar1="\033[1;$[$RANDOM%6+31]m*\033[0m"
if [[ ! "$topline" =~ ^[1-9][0-9]*$ ]];then
#列印數字1的邊
if [ "$i" -ne 1 ];then
echo -en "${_color1}1$_color2"
echo -e "${_color1}3$_color2"
#bash colorsanjiao.sh
請輸入總的行數:12
3
1*3
1***3
12222222222222222222223
唉,這微網誌的編輯器讓我原來的排版不美觀了。希望不影響各位
#b.sh
#定義顔色開關
_cr1="\033[1;"
_cr2="m \033[0m"
####################################################
num=4
for i in <code>seq $num</code>;do
#列印列顔色方格
for j in <code>seq $num</code>;do
echo -e "${_cr1}43${_cr2}\c"
echo -e "${_cr1}44${_cr2}\c"
#列印行顔色方格
for k in <code>seq $num</code>;do
a.sh
line=8
line2=$[line*2]
for i in <code>seq 1 8</code> ; do
for j in <code>seq 1 $line2</code> ; do
if [ $[i%2] -eq 1 ] ; then
if [ $[j%4] -eq 1 -o $[j%4] -eq 2 ] ; then
echo -ne "\033[41m \033[0m"
echo -ne "\033[42m \033[0m"
real 0m2.928s
user 0m1.012s
sys 0m1.958s
b.sh
real 0m2.622s
user 0m0.688s
sys 0m1.973s
real 0m3.188s
user 0m1.132s
sys 0m2.070s
real 0m2.571s
user 0m0.669s
sys 0m1.947s
real 0m2.867s
user 0m0.956s
sys 0m1.961s
real 0m2.217s
user 0m0.544s
sys
最後一個可以自定義顔色和方格數的
截圖:

版權聲明:原創作品,如需轉載,請注明出處。否則将追究法律責任
本文轉自 ljpwinxp 51CTO部落格,原文連結:http://blog.51cto.com/191226139/2055595