鍍金池/ 教程/ Linux/ shell 學習三十天---break,continue,shift,getopts
shell 學習四十五天---xargs
shell學習第三天
shell 學習十五天---join 連接字段
shell 學習第二天
shell 學習四十三天---臨時性文件的建立與使用
shell 學習第六天---小結(jié)
shell 學習三十三天---關(guān)于重定向
shell 學習二十九天---循環(huán)
shell 學習二十四天---提取開頭或結(jié)尾數(shù)行
shell 學習第十天---sed 查找與替換
shell 學習第十一天---sed 正則的精確控制
shell 學習三十天---break,continue,shift,getopts
shell 學習---小結(jié)
shell 學習三十一天---函數(shù)問題
shell 學習第四天---華麗的 printf 輸出
shell 學習三十五天---波浪號展開與通配符
shell 學習十九天---文本塊排序
shell 學習十二天---行與字符串
shell 學習二十一天---重新格式化段落
shell 學習十八天---文本排序
shell 學習十三天---sed 案例分析
shell 學習四十一天---列出文件 ls 和 od 命令
shell 學習十七天---awk 命令
shell 學習三十六天---命令替換
shell 學習十六天---join 練習
shell 學習三十二天---read 讀取一行
shell 學習二十二天---計算行數(shù),字數(shù)以及字符數(shù)
shell 學習小總結(jié)---本章小結(jié)
shell 學習第八天---擴展正則表達式(ERE)
shell 學習四十二天---使用 touch 更新文件時間
shell 學習二十八天---case 語句
shell 學習三十九天---內(nèi)建命令
shell 學習第一天
shell 學習三十四天---printf 詳解
shell 學習二十六天---變量與算數(shù)
shell 學習三十八天---執(zhí)行順序和 eval
shell 學習四十四天---尋找文件
shell 學習二十五天---神器的管道符
shell 學習十四天---使用 cut 選定字段
shell 學習第五天---基本的I/O重定向
shell 學習四十天---awk 的驚人表現(xiàn)
shell 學習二十天---sort 的其他內(nèi)容以及 uniq 命令
shell 學習二十三天---打印
shell 學習第九天---分組
shell 學習四十八天---文件校驗和匹配
shell 學習二十七天---退出狀態(tài)和 if 語句
shell 學習四十七天---文件比較 cmp,diff,patch
shell 學習第七天---基礎(chǔ)正則表達式(BRE)
shell 學習四十六天---文件系統(tǒng)的空間信息 df 和 du 命令
shell 學習三十七天---引用
shell 學習小結(jié)

shell 學習三十天---break,continue,shift,getopts

這兩個命令分別用來退出循環(huán),或跳到循環(huán)體的其他地方.
使用 while 與 break,等待用戶登錄
bash 代碼:

printf “Enter username: ”  
read user  
while true  
do  
if who | grep “$user” >/dev/null  
then   
break;  
fi  
sleep 30  
done  

等待特定用戶,每 30 秒確認一次

true 命令什么事也不必做,只是成功的退出.這用于編寫無限循環(huán),即會永久的執(zhí)行循環(huán).在編寫無限循環(huán)時,必須放置一個退出條件在循環(huán)體內(nèi),正如這里所作的.另有一個 false 命令和它有點相似,只是很少的用到,也不做人和事,僅表示不成功的狀態(tài).false 命令常見于無線的 until false..循環(huán)中.

continue 命令則用于提早的開始下一段重復動作,也就是在到大循環(huán)體的底部之前.
break 與 continue 命令都可以接受可選的數(shù)值參數(shù),可分別用來之處要中斷(break)或繼續(xù)多少個被包含的循環(huán)(如果循環(huán)技術(shù)需要的是一個在運行時可被計算的表達式時,可以使用$((...)) ).案例:
while condition1 //外循環(huán)
do...
while condition2 //內(nèi)循環(huán)
do..
break; 外循環(huán)的終端
done
done
break 與 continue 特別具備終端或繼續(xù)多個循環(huán)層的能力.從而以簡潔的形式彌補了 shell 語言里缺乏 goto 關(guān)鍵字的不足.
使用 continue 的案例:

 #!/bin/bash  
limit=19   
echo "printing Number 1 throught 20"  
a=0  
while [ $a -le "$limit" ]  
do  
        let a++  
        #let a+=1  
        #a=$(($a+1))  
        if [ "$a" -eq 3 ] || [ "$a" -eq 11 ]  
        then  
                continue  
        fi  
        echo -n "$a "  
done  

輸出結(jié)果:
printing Number 1 throught 20
1 2 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20
由此可見 continue 的作用是結(jié)束本次循環(huán),執(zhí)行下一次循環(huán)

使用 break 的案例:

 #!/bin/bash  
limit=19  
echo "printing Number 1 throught 20"  
a=0  
while [ $a -le "$limit" ]  
do  
        let a++  
        #let a+=1  
        #a=$(($a+1))  
        if [ "$a" -eq 3 ] || [ "$a" -eq 11 ]  
        then  
                break  
        fi  
        echo -n "$a "  
done  

輸出結(jié)果:
printing Number 1 throught 20
1 2
由此可見,break 的作用是退出當前循環(huán).

shift
我們知道,對于位置變量或命令行參數(shù),其個數(shù)必須是確定的,或者當 Shell 程序不知道其個數(shù)時,可以把所有參數(shù)一起賦值給變量$*。若用戶要求 Shell 在不知道位置變量個數(shù)的情況下,還能逐個的把參數(shù)一一處理,也就是在 $1 后為 $2,在 $2 后面為 $3 等。在 shift 命令執(zhí)行前變量 $1 的值在 shift 命令執(zhí)行后就不可用了。
案例:

 #!/bin/bash  
until [ $# -eq 0 ]  
do  
        echo "第一個參數(shù)為: $1 參數(shù)個數(shù)為: $#"  
        shift  
done  

執(zhí)行命令:./shift.sh 1 2 3 4
輸出為:
第一個參數(shù)為: 1 參數(shù)個數(shù)為: 4
第一個參數(shù)為: 2 參數(shù)個數(shù)為: 3
第一個參數(shù)為: 3 參數(shù)個數(shù)為: 2
第一個參數(shù)為: 4 參數(shù)個數(shù)為: 1
分析:從上可知 shift 命令每執(zhí)行一次,變量的個數(shù)($#)減一,而變量值提前一位.
shift 可以用來向左移動位置參數(shù)。
Shell 的名字 $0
第一個參數(shù) $1
第二個參數(shù) $2
第 n 個參數(shù) $n
所有參數(shù) $@ 或 $*
參數(shù)個數(shù) $#
案例:
bash 代碼:

until [ -z "$1" ]  # Until all parameters used up
do
  echo "$@ "
  shift
done

命令: ./shift1.sh 1 2 3 4 5 6 7 8 9 10
輸出:

1 2 3 4 5 6 7 8 9 10  
2 3 4 5 6 7 8 9 10   
3 4 5 6 7 8 9 10   
4 5 6 7 8 9 10  
5 6 7 8 9 10  
6 7 8 9 10  
7 8 9 10  
8 9 10  
9 10  
10   

getopts 命令
語法:
getopts option_spec variable [ arguments...]
線來看一個簡單的例子:

 #!/bin/bash  
echo $*  
while getopts ":a:bc:" opt  
do  
        case $opt in  
                a)  
                echo $OPTARG  
                echo $OPTIND  
                ;;  
                b)  
                echo "b $OPTIND"  
                ;;  
                c)  
                echo "c $OPTIND"  
                ;;  
                ?)  
                echo "error"  
                exit 1  
        esac  
done  
echo $OPTIND  
shift $(( $OPTIND-1 ))  
echo $0  
echo $*   

如果執(zhí)行命令:./getopts.sh -a 11 -b -c 6
結(jié)果為:

-a 11 -b -c 6  
11  
3  
b 4  
c 6   
6  

./getopts.sh

看分析:
getopts 后面的字符串就是可以使用的選項列表,每個字母代表一個選項,后面帶:的意味著選項除了定義本身之外,還會帶上一個參數(shù)作為選項的值,比如 a:在實際的使用中就會對應-a 11,選項的值就是 11;getopts 字符串中沒有跟隨:的是開關(guān)型選項,不需要再指定值,相當于 true/false,只要帶了這個參數(shù)就是 true。如果命令行中包含了沒有在 getopts 列表中的選項,會有警告信息,如果在整個 getopts 字符串前面也加上個:,就能消除警告信息了。
使用 getopts 識別出各個選項之后,就可以配合 case 來進行相應的操作了。
optarg 這個變變,getopts 修改了這個變量。
這里變量$optarg 存儲相應選項的參數(shù),而$optind 總是存儲原始$*中下一個要處理的元素(不是參數(shù),而是選項,此處值得的是 a,b,c 這三個選線,而不是那些數(shù)字,當然數(shù)字也是會占有位置的)位置。
while getopts ":a:bc:" opt #第一個冒號表示忽略錯誤;字符后面的冒號表示該選項必須有自己的參數(shù).

使用 getopts 處理參數(shù)雖然是方便,但仍然有兩個小小的局限:

  1. 選項參數(shù)的格式必須是-d val,而不能是中間沒有空格的-dval。
  2. 所有選項參數(shù)必須寫在其它參數(shù)的前面,因為 getopts 是從命令行前面開始處理,遇到非-開頭的參數(shù),或者選項參數(shù)結(jié)束標記--就中止了,如果中間遇到非選項的命令行參數(shù),后面的選項參數(shù)就都取不到了。
  3. 不支持長選項, 也就是--debug 之類的選項

案例:

 #!/bin/bash  
while getopts "ab:cd:" opt  
do  
        case $opt in   
                a)  
                echo $OPTIND  
                ;;  
                b)  
                echo $OPTIND  
                echo $OPTARG  
                ;;  
                c)  
                echo $OPTIND  
                ;;  
                d)  
                echo $OPTIND  
                echo $OPTARG  
        esac  
done  
shift $(($OPTIND-1))  

使用命令:./getopts1.sh -a -b foo -c -d haha
得到結(jié)果:

2  
4  
foo  
5  
7  
haha 

最后使用 shift $(($OPTIND-1))的作用是:通過 shift $(($OPTIND - 1))的處理,$*中就只保留了除去選項內(nèi)容的參數(shù),可以在其后進行正常的 shell 編程處理了。 貌似不用也可以.
如果出現(xiàn)這種情況:
getopts “:ab:c”第一個冒號代表的含義是:第一個冒號表示忽略錯誤,即當出現(xiàn)沒有的選項是會忽略;字符后面的冒號表示該選項必須有自己的參數(shù),