標籤:for if
數組
變數:記憶體的儲存空間;
變數的特點:每個變數中只能存放一個資料,變數只能進行一次性賦值
數組:存放一個或多個元素的連續的記憶體空間;相當於多個變數的集合
數組元素:在數組中任何一個存放資料的儲存單元
數組的索引:
1.數字索引:索引數組 (Index ARRAY)
0,1,2,,,,,,
2.名稱(有意義的字串):關聯陣列 (Related ARRAY) (用的較少)
稠密數組和稀疏數組:
稠密數組:索引編號必須連續
稀疏數組:索引編號可以不連續, bash數組就屬於此類
定義(聲明)數組:
1.declare命令
declare -i NAME :將NAME聲明為整型變數
-x :將NAME聲明為環境變數
declare -a NAME :將NAME聲明為索引數組(如果支援)
declare -A NAME :將NAME聲明為關聯陣列(如果支援)
declare -a NAME=("VALU1" "VALLU2" "VALU3"...)
declare -a NAMEE=([0]="value1" [1]="value2" [5]="value3")
2.直接聲明數組:
直接為數組賦值:
ARRAY_NAME=("VALU1" "VALLU2" "VALU3"...): 聲明稠密數組
ARRAY_NAME=([0]="value1" [1]="value2" [5]="value3") 聲明稀疏數組
3.定義數組的元素而建立的數組:
ARRAY_NAME=[0]=value1
ARRAY_NAME=[1]=value2
引用數組中元素:
引用變數的方法 :${NAME}
引用數組元素的方法: ${ARRAY_NAME[INDEX]}
注意如果不給出索引號,則表示引用數組的第一個元素即INDEX=0的元素
引用整個數組的所有元素:${ARRAY_NAME[*]}或者${ARRAY_NAME[@]}
引用數組的索引:${!ARRAY_NAME[*]} 或 ${!ARRAY_NAME[@]}
查看數組的長度(數組中有效元素的個數)
${#ARRAY_NAME[*]} 或 ${#ARRAY_NAME[@]}
數組切片:
${ARRAY_NAME:offset}:顯示包括offset數字所表示的索引位置及以後德所有元素
${ARRAY_NAME:offset:number}:顯示包括offset數字所表示的索引位置及以後number個元素
向數組中追加元素
1.稠密數組:
ARRAY_NAME[{$#ARRAY_NAME[*]}]=valueN
2.稀疏數組:
ARRAY_NAME[INDEX]=valueN
注意:INDEX必須為未被使用的數組元素索引編號
撤銷數組:
unset ARRAY_NAME
刪除數組中的元素:
unset ARRAY_NAME[INDEX]
RANDOM變數 0-32767
熵池
/dev/random
/dev/urandom
bash指令碼編程:
shell指令碼編程的特點:
過程式程式設計語言
指令碼類語言
解釋型語言
過程式程式設計語言:
順序執行結構:
以從左至右,從上到下順序執行所有的語句(命令)
shell指令碼的主體結構;
選擇執行結構:
依照給定條件的邏輯判斷結果或者依照可選的取值範圍,進而選擇某個分支中的語句來執行;
if:分支選擇標準:邏輯判斷的結果;
case:分支選擇標準:根據可選的取值;
迴圈執行結構:
對於某特定語句,重複執行0次,1次或多次;
for:遍曆指定的列表;
while:根據邏輯判斷的結果;
until:根據邏輯判斷的結果;
select:死迴圈,利用迴圈機制提供挑選清單;
選擇執行結構:
if語句:
if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi
if語句單分支結構:如果條件為真,則執行then後的命令,否則,不做任何操作;
if CONDITION
then STATEMENT
fi
if CONDITION ; then
STATEMENT1
STATEMENT2
...
fi
注意:想要執行then後面的STATEMENTS,前提條件是CONDITION部分為真;
if語句的雙分支結構:如果條件為真,就執行then後面的命令;否則就執行else後面的命令;
if CONDITION ; then
STATEMENT
...
else
STATEMENT
...
fi
if語句的多分支結構:首先判斷CONDITION1是否為真,如果為真,則執行第一個then後面的語句;否則就判斷CONDITION2是否為真,如果為真,就執行第二個then後面的語句;否則就判斷CONDITION3是否為真,如果為真,就執行第三個then後面的語句...;如果所有的CONDITION都為假,就執行else後面的語句;
if CONDITION1 ; then
STATEMENT
...
elif CONDITION2 ; then
STATEMENT
...
elif CONDITION3 ; then
STATEMENT
...
...
else
STATEMENT
...
fi
建議:if多分支結構,能不用就不用;
bash指令碼編程之使用者互動:
位置參數變數:$1, $2, $3, ...
特殊變數:
$#:所有的位置參數的總數;
$*:給出的所有位置參數的列表;當使用雙引號引用時,整個參數列表被當做一個字串;
[email protected]:給出的所有位置參數的列表;當時有雙引號引用時,每個參數作為單獨的字串存在;
$0:所執行的指令檔自身的路徑;
eg: 寫一個指令碼,給指令碼傳遞使用者名稱參數,判斷參數數量是否合格;並且判斷使用者是否存在,如果存在,就顯示相應資訊;否則就建立之並為其設定密碼;
#!/bin/bash
#
if [ $# -ne 1 ] ; then
echo "Only ONE USERNAME can be specified."
exit 5
fi
if id $1 &> /dev/null ; then
echo "$1 exists already."
else
useradd $1
echo $1 | passwd --stdin $1 &> /dev/null
echo "Create $1 successfully."
fi
read命令:
read [-a 數組] [-p 提示符] [-t 逾時] [名稱 ...]
名稱一般為變數名或數組名:如果不寫名稱,則系統會將read讀到的資訊儲存在REPLY變數中;
注意:在使用read命令的時候,通常會使用-t選項來規定逾時時間;一旦使用-t選項定義了逾時時間,我們必須在後面判斷給定的變數是否為空白,如果為空白需要為變數提供預設值;
eg: 能夠添加或刪除使用者賬戶,可以使用-a選項完成添加,使用-d選項完成刪除使用者;
#!/bin/bash
#
if [ $# -ne 2 ] ; then
echo "Usage: $(basename $0) -a Username | -d Username."
exit 5
fi
if [ $1 == ‘-a‘ ] ; then
if id $2 &> /dev/null ; then
echo "$2 exists already."
else
useradd $2
echo $2 | passwd --stdin $2 &> /dev/null
echo "Create $2 successfully."
fi
fi
if [ $1 == ‘-d‘ ] ; then
if id $2 &> /dev/null ; then
userdel -r $2
echo "Delte $2 finished."
else
echo "User $2 does not exist."
fi
fi
eg:. 判斷給出的檔案大小是否大於100KB,如果大於100KB,就顯示這是個大檔案;否則就顯示這是個小檔案;
#!/bin/bash
#
FILESIZE=$(wc -c < $1)
if [ $FILESIZE -le 102400 ] ; then
echo "Big file."
else
echo "Small file."
fi
eg: 判斷給出的一個字串是否為整數
#!/bin/bash
#
if echo $1 | grep "^\<[[:digit:]]\+\>$" &> /dev/null ; then
echo "$1 is integer."
else
echo "$1 is not integer."
fi
位置參數變數:
$1, $2, $3, ...
shift [n]
移位位置參數。
eg: 能夠添加或刪除使用者賬戶,可以使用-a選項完成添加,使用-d選項完成刪除使用者;
#!/bin/bash
# Author: zhao
# Version: 0.0.2
# Determine Paraments count
#
if [ $# -ne 2 ] ; then
echo "Usage: $(basename $0) -a Username | -d Username."
exit 5
fi
if [ $1 == ‘-a‘ ] ; then
shift
if id $1 &> /dev/null ; then
echo "$1 exists already."
else
useradd $1
echo $1 | passwd --stdin $1 &> /dev/null
echo "Create $1 successfully."
fi
fi
if [ $1 == ‘-d‘ ] ; then
shift
if id $1 &> /dev/null ; then
userdel -r $1
echo "Delte $1 finished."
else
echo "User $1 does not exist."
fi
fi
if語句多分支結構:
if CONDITION1 ; then
STATEMENT
...
elif CONDITION2 ; then
STATEMENT
...
elif CONDITION3 ; then
STATEMENT
...
...
else
STATEMENT
...
fi
eg:
從/etc/passwd中UID和GID相同的使用者中隨機播放一個使用者,判斷該使用者的類型:UID為0-->超級使用者;UID在1-999之間-->系統使用者;1000+登入使用者;
#!/bin/bash
#
LINES=$(egrep "\<([[:digit:]]+)\>.*\1" /etc/passwd | wc -l)
SEQUENCE=$[${RANDOM}%${LINES}+1]
USERNAME=$(egrep "\<([[:digit:]]+)\>.*\1" /etc/passwd | head -n ${SEQUENCE} | tail -1 | cut -d: -f1)
USERID=$(egrep "\<([[:digit:]]+)\>.*\1" /etc/passwd | head -n ${SEQUENCE} | tail -1 | cut -d: -f3)
if [ $USERID -eq 0 ] ; then
echo "$USERNAME is Super user."
elif [ $USERID -ge 1000 ] ; then
echo "$USERNAME is Login User."
else
echo "$USERNAME is System User."
fi
迴圈執行結構:
將一段代碼重複的執行0次、1次或多次;
一個好的迴圈結構,必須要包括兩個最重要的環節:
進入迴圈的條件:
開始迴圈時所滿足的條件;
退出迴圈的條件:
迴圈結束所滿足的條件;
bash指令碼:
for
while
until
select
for迴圈:
1.遍曆列表
for VAR_NAME in LIST ; do 迴圈體; done
for VAR_NAME in LIST ; do
迴圈體
done
VAR_NAME:任意指定的變數名稱,變數的值是從LIST中取值並賦值的;
迴圈體:一般來說是能夠用到VAR_NAME的命令或命令的組合;如果迴圈體中沒有包括VAR_NAME,則可能出現死迴圈;
LIST的產生方式:
1) 直接給出
2) 純整數列表
seq:輸出一個整數列表
seq [FIRST [INCREMENT]] LAST
3) 花括弧展開
{FIRST..LAST}
4) 命令的執行結果的傳回值
5) GLOBBING
6) 某些變數的引用:[email protected], $*
eg:
能夠添加或刪除使用者賬戶,可以使用-a選項完成添加一個或多個使用者,使用-d選項完成刪除一個或多個使用者;
樣本:
#!/bin/bash
#
if [ $# -lt 2 ] ; then
echo "Usage: $(basename $0) -a User1 User2 ... | -d User1 User2 ..."
exit 5
fi
if [ $1 == ‘-a‘ ] ; then
shift
for I in $* ; do
if id $I &> /dev/null ; then
echo "$I exists already."
else
useradd $I
echo $I | passwd --stdin $I &> /dev/null
echo "Create $I successfully."
fi
done
fi
if [ $1 == ‘-d‘ ] ; then
shift
for J in $* ; do
if id $J &> /dev/null ; then
userdel -r $J
echo "Delte $J finished."
else
echo "User $J does not exist."
fi
done
fi
for迴圈:
進入迴圈的條件:LIST中有元素可以取用;
退出迴圈的條件:LIST中以被取空,再無元素可用;
for迴圈的特點:
1.幾乎不會出現死迴圈;
2.在執行迴圈的過程中,需要將這個LIST載入記憶體;因此對於大列表來說可能會過多的消耗記憶體和CPU資源;
eg:計算100以內所有整數的和;
#!/bin/bash
#
read -t 5 -p "Please input a integer[0]: " INTEGER
if [ -z $INTEGER ] ; then
INTEGER=0
fi
if ! echo $INTEGER | grep -q "^\<[[:digit:]]\+\>$" ; then
echo "You must input an integer."
exit 5
fi
for I in $(seq $INTEGER) ; do
# let SUM+=$I
# let SUM=$SUM+$I
SUM=$[SUM+I]
done
echo $SUM
eg: 寫一個指令碼,列印由*組成的倒置的等腰三角形;
#!/bin/bash
#
LINENUM=$1
for I in $(seq $LINENUM) ; do
for J in $(seq $[I-1]) ; do
echo -n " "
done
for K in $(seq $[2*(LINENUM-I)+1]) ; do
echo -n "*"
done
echo
done
eg: 列印九九乘法表
#!/bin/bash
#
for I in {1..9} ; do
for J in $(seq $I) ; do
echo -ne "$I*$J=$[I*J]\t"
done
echo
done
1X1=1 1X2=2 1X3=3 ... 1X9=9
2X2=4 2X3=6 ... 2X9=18
...
9X9=81
注意:使用for迴圈嵌套的時候,外層for迴圈,控制行數的輸出;內層for迴圈,控制列數的輸出;
2.控制變數
for (( 運算式1; 運算式2; 運算式3 )); do 命令; done
for (( 運算式1; 運算式2; 運算式3 )) ; do
迴圈體
done
運算式1:為變數賦初始值;
運算式2:迴圈的允出準則;
運算式3:變數值的變化規律;
Linux初學之數組及if語句for迴圈