bash腳本中 if 語句 和 for 語句的用法
順序執行 (從左到右,從上到下的執行)
選擇執行 (條件滿足或者不滿足的時候,才會執行某段結構)
循環執行 (重復執行某段結構)
今天所寫的if 就是選擇順序,for就是循環執行
在if或者for中不可避免的要使用一些結構,還有一些運算方法,我先把這些列出來,方便以後使用。
算術運算方法:
1.$[expression]
其中的表達式可以是純數字組成的,也可以使用變量引用變量值;在使用變量時,可以將$符號省略;
示例:
# echo $[3+4]
# NUM1=5 ; NUM2=4 ; echo $[NUM1*NUM2]
2.let VAR=EXPRESSION
根據算術表達式完成算術運算並賦值給指定的變量;
3.$((EXPRESSION))
其中的表達式可以是純數字組成的,也可以使用變量引用變量值;在使用變量時,可以將$符號省略;
4.expr ARGU1 ARGU2 ARGU3
其中ARGU1和ARGU3必須是整數數值;ARGU2是算術運算符;
5.echo "EXPRESSION" | bc
6.bc <<< EXPRESSION
位置參數變量:
$0:命令的本身,對於腳本而言,就是該腳本的路徑;
$1,$2.....$n:腳本後面通過命令行給腳本傳遞的命令行參數;
n>9時,引用該位置變量時,需要加{},即${10}
特殊變量:
$@:給出的所有位置參數的列表,當使用雙引號引用時,每個參數作為單獨的字符串存在;
$*:給出的所有位置參數的列表,當使用雙引號引用時,整個參數列表被當做一個字符串;
shift命令,可以將$2->$1;
if語句:
if: if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi
if語句的單分支結構:
if 命令; then 命令; fi
註意:是否會執行then後面的命令,取決於if後面的命令的執行狀態返回值;
1.如果其返回值為真,則執行then後面的命令;
2.如果其但回執為假,則不執行then後面的命令;
建議在腳本中的書寫格式:
if CONDITION ; then
STATEMENT
..
fi
或
if CONDITION ;
then
STATEMENT
..
fi
if語句的雙分支結構:
if 命令; then 命令; else 命令; fi
註意:是否會執行then或else後面的命令,取決於if後面的命令的執行狀態返回值;
1.如果其返回值為真,則執行then後面的命令;
2.如果其但回執為假,則執行else後面的命令;
建議在腳本中的書寫格式:
if CONDITION ; then
STATEMENT
..
else
STATEMENT
..
fi
或
if CONDITION ;
then
STATEMENT
..
else
STATEMENT
..
fi
if語句的多分支結構:(不建議使用,太麻煩,我們可以用下邊的方法,進行單個或者多個的嵌套解決)
if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi
註意:是否會執行then或else後面的命令,取決於if後面的命令的執行狀態返回值或者elif後面的命令的執行狀態返回值;
1.首先判斷if後面的命令的狀態返回值是否為真,如果為真,就執行then後面的語句;如果為假,就繼續判斷第一個elif後面的命令的執行狀態返回值;
2.第一個elif後面的命令的執行狀態返回值為真,就執行第一個elif語句中then後面的命令,否則,就繼續判斷第二個elif後面的命令執行狀態返回值;
3.以此類推,會判斷每個elif後面的命令的執行狀態返回值是否為真,如果所有的if和elif後面的命令的執行狀態返回值均為假,則執行else後面的語句;
建議在腳本中的書寫格式:
if CONDITION ; then
STATEMENT
..
elif CONDITION2 ; then
STATEMENT
..
else ; then
STATEMENT
..
fi
或
if CONDITION ;
then
STATEMENT
..
elif CONDITION2 ; then
STATEMENT
..
else
STATEMENT
..
fi
註意:if的多分支結構,使用場景不多,而且有些時候,可以使用嵌套的單分支或雙分支if結構代替if多分支結構;
嵌套的if結構:
if CONTITIONG1 ; then
if CONTITIONG2 ; then
if CONTITIONG3 ; then
STATEMENT
..
else
STATEMENT
fi
else
STATEMENT
fi
else
STATEMENT
fi
一個好的循環結構,必須包括兩個重要的環節;
1.進入循環的條件:
在符合要求或滿足條件時才開始循環;
2.退出循環的條件:
達到某個要求或符合某個條件時需要結束或終止循環的執行;
for循環:
1.遍歷列表的循環:
為列表中的每個成員執行命令。
for 名稱 [in 詞語 ... ] ; do 命令; done
建議在腳本中書寫的格式:
for VAR_NAME in LIST ; do
循環體
done
或
for VAR_NAME in LIST
do
循環體
done
註意:
VAR_NAME:任意指定的變量名稱,變量的值是從LIST中遍歷獲取的各個元素;
LIST:for循環需要遍歷的列表;可以通過以下方式生成列表;
1.直接給出列表;
2.純整數列表;
1)花括號展開:
{FIRSTNUM..LASTNUM}
{FIRST,SECOND,THIRD,...,LAST}
2)seq命令
seq [OPTION]... LAST
seq [OPTION]... FIRST LAST
seq [OPTION]... FIRST INCREMENT LAST
3.花括號展開:
{FIRST..LAST}
4.命令的執行結果:
ls /etc
5.GLOBBING通配符
6.某些特殊變量的值:
$*,$@
循環體:
一般來說,循環體中應該能夠用到VAR_NAME變量的值的命令或命令的組合;如果循環體中的命令並沒有用到VAR_NAME變量的值的話,列表的元素個數,就是此次for循環的次數;
1.進入循環的條件,LIST中尚有未被取盡的元素;
2.退出循環的條件,LIST中的元素被取盡;
3.for循環幾乎不會出現死循環;
4.在執行循環的過程中,需要將整個LIST載入內存,因此。對於大列表來說,可能會消耗比較多的內存及CPU資源;
簡單的例子(vim編輯內容)
1.傳遞一個字符串給腳本,腳本會將該字符串當作用戶名,如果該用戶不存在,則添加之並為其設置與用戶名相同的密碼。
#!/bin/bash # if [ $# -ne 1 ] ; then echo "please input one name charast" exit 6; fi if id $1 &> /dev/null ; then echo "This user already exists" else useradd $1 &> /dev/null echo $1 | passwd --stdin $1 &> /dev/null echo "This user creat and password is username" fi
2.將兩個文本文件的路徑傳遞給腳本作為其參數,如果有文件不存在,則結束腳本執行並報告錯誤信息;如果文件都存在,則比較兩個文件中哪個文件的行數多,返回行數多的文件的文件名。
#!/bin/bash # read -p "Please input two files: " FILE1 FILE2 if ! cat $FILE1 &> /dev/null ; then echo "please enter the first true path file" exit 5 if ! cat $FILE2 &> /dev/null ;then echo "please enter the second true path file" exit 5 fi fi LINE1=$(cat $FILE1 | wc -l ) LINE2=$(cat $FILE2 | wc -l ) if [ $LINE1 -ne $LINE2 ] ; then if [ $LINE1 -gt $LINE2 ] ; then echo "$FILE1" else echo "$FILE2" fi else echo "$FILE1 and $FILE2 are generally long" fi unset FILE1 FILE2 LINE1 LINE2
3.利用RANDOM變量隨機生成十個數字,顯示出這十個數字,並顯示出其中的最大值和最小值。
#!/bin/bash # touch /tmp/math.txt for I in $(seq 1 10) ; do J=$RANDOM echo "$J " echo "$J" >> /tmp/math.txt done K=$( sort -n /tmp/math.txt | head -1) L=$( sort -n /tmp/math.txt | tail -1) echo "laster $L ; leaster $K " rm -rf /tmp/math.txt exit 5
4.給腳本傳遞一個數字作為行總數,分別打印由*組成的最0小銳角朝上和朝下的等腰三角形以及菱形。
#!/bin/bash # read -p "enter one number: " INT if [[ $INT =~ [^[:digit:]] ]] ; then echo "please enter the number" exit 5 fi echo ”zheng sanjiao“ for I in $(seq $INT) ; do for J in $(seq $[INT-I]) ; do echo -n " " done for K in $(seq $[2*I-1]) ; do echo -n "*" done echo done echo "dao sanjiao" for M in $(seq $INT) ; do for B in $(seq $[M-1]) ; do echo -n " " done for N in $(seq $[2*(INT-M)+1]) ; do echo -n "*" done echo done echo "lingxing" if [ $[INT%2] -ne 0 ] ; then INT2=$[(INT+1)/2] for Q in $(seq $INT2) ; do for W in $(seq $[INT2-Q]) ; do echo -n " " done for E in $(seq $[2*Q-1]) ; do echo -n "*" done echo done for R in $(seq $[INT2-1]) ; do for T in $(seq $[R]) ; do echo -n " " done for Y in $(seq $[2*(INT2-R)-1]) ; do echo -n "*" done echo done exit 7 else echo "qing shuru jishu >3" fi
5.分別打印順序和旋轉的九九乘法表。
順序的九九乘法表是正常的九九乘法表;
旋轉的九九乘法表是第一行是1×1=1 1×2=2 1×3=3 1×4=4 ... 1×9=9; 第二行是2×2=4 2×3=6 2×4=8 ... 2×9=18; ... 第九行是9×9=81;
#!/bin/bash # for I in $(seq 1 9) ; do for J in $(seq 1 $I) ;do echo -ne "$I×$J=$[I*J]\t" done echo done for M in $(seq 1 9) ; do for N in $(seq $M 9) ; do echo -ne "$M×$N=$[N*M]\t" done echo done
bash腳本中 if 語句 和 for 語句的用法