上回我們研究和探討了Linux shell編程中for 循環(huán)語句,與在C/C++中一樣,for 循環(huán)語句Linux shell編程中有很多靈活的用法。今天我們來研究和探討while循環(huán)語句。
一、數(shù)字條件循環(huán)
我們繼續(xù)以for循環(huán)語句中的例子,計算 從1到10與2的乘積?并輸出。
(一)常規(guī)寫法
1.在zsh命令行中
# csdn @ edu in ~ [20:35:57]?
$ i=1; while (( $i <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; i=$(expr $i + 1); done
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
10 * 2 = 20# csdn @ edu in ~ [20:36:21]?
$?
2.在bash命令行中
[csdn ~]$ i=1; while (( $i <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; i=$(expr $i + 1); done
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
10 * 2 = 20
3.注意
表達(dá)式 $(expr $i \* 2)? ? ?中?\*?前后要用空格與操作數(shù)分隔,表達(dá)式 i=$(expr $i + 1) ?中 + 前后要用空格與操作數(shù)分隔,否則結(jié)果就會出錯。
(二)使用++運(yùn)算符來改變循環(huán)變量
對于經(jīng)常使用i++、i--運(yùn)算符的程序員來說,使用i=i+1多多少少有些別扭。
由于i++或++i是表達(dá)式而不是命令,所以我們在使用這種表達(dá)式時要變通一下。
1.通過let命令來使用++運(yùn)算符
(1)在zsh命令行中
# csdn @ edu in ~ [21:08:50]?
$ i=1; while (( $i <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; let i++; done
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
10 * 2 = 20# csdn @ edu in ~ [21:09:03]?
$?
?
?(2)在bash命令行中
[csdn ~]$ i=1; while (( $i <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; let i++; done
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
10 * 2 = 20
[csdn ~]$?
2.在循環(huán)條件表達(dá)式中用++修改循環(huán)變量值?
(1)在zsh命令行中
# csdn @ edu in ~ [21:21:29]?
$ i=1; while (( i++ <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; done
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
10 * 2 = 20
11 * 2 = 22# csdn @ edu in ~ [21:21:40]?
$?
(2)在bash命令行中
[csdn ~]$ i=1; while (( i++ <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; done
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
10 * 2 = 20
11 * 2 = 22
[csdn ~]$?
3. 在循環(huán)條件表達(dá)式中利用 && 和 ++修改循環(huán)變量值?
(1)在zsh命令行中
# csdn @ edu in ~ [21:31:12]?
$ i=0; while (( i++ && i <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; done# csdn @ edu in ~ [21:38:46]?
$ i=0; while (( ++i && i <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; done
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
10 * 2 = 20# csdn @ edu in ~ [21:39:10]?
$?
(2)在bash命令行中
[csdn ~]$ i=0; while (( i++ && i <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; done
[csdn ~]$ i=0; while (( ++i && i <= 10 )) ; do ?echo "$i * 2 = $(expr $i \* 2)"; done
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
10 * 2 = 20
[csdn ~]$?
(3)注意
在上面的實(shí)例中,使用?i++ && i <= 10 作為循環(huán)條件表達(dá)式時,沒有輸出結(jié)果。
使用? ++i && i <= 10??作為循環(huán)條件表達(dá)式才能正確輸出結(jié)果。
二、字符條件類循環(huán)
(一)實(shí)例1
我們先定義一個數(shù)組s=(b d 3 0),并以0作為最后一個數(shù)組元素,然后定義循環(huán)變量i并初始化,接著使用while循環(huán)逐一訪問數(shù)組s的成員值并輸出,如果成員值?是小寫字母,就是輸出提示is a lowercase letter,否則輸出提示is not a letter,直到遇到最后一個數(shù)組元素0,循環(huán)結(jié)束。
1.zsh中
命令行為:
s=(b d 3 0); i=1; while [[ ${s[i]} != '0' ]] ; do if [[ ${s[i]} > 'a' && ${s[i]} < 'z' ]]; then echo ${s[i]} is a lowercase letter; else echo ${s[i]} is not a letter; fi; let i++; done
由于CSDN程序員研修院提供的linux環(huán)境不能讓以上命令完整顯示,所以我們分幾行輸入:
# csdn @ edu in ~ [12:23:33]?
$ s=(b d 3 0); i=1; while [[ ${s[i]} != '0' ]] ;?
while> do if [[ ${s[i]} > 'a' && ${s[i]} < 'z' ]]; then echo ${s[i]} is a lowercase letter; else echo ${s[i]} is not a letter; fi;?
while> let i++;
while> done
b is a lowercase letter
d is a lowercase letter
3 is not a letter# csdn @ edu in ~ [12:24:31]?
$?
?
注意:在zsh中,數(shù)組下標(biāo)是從1開始的。所以上例中數(shù)組下標(biāo)變量i的初始值為1。
2.在bash中
s=(b d 3 0); i=0; while [[ ${s[i]} != '0' ]] ; do if [[ ${s[i]} > 'a' && ${s[i]} < 'z' ]]; then echo ${s[i]} is a lowercase letter; else echo ${s[i]} is not a letter; fi; let i++; done
user?@?host?:?~?$?s=(b?d?3?0);?i=0;?while?[[?${s[i]}?!=?'0'?]]?;?do?if?[[?${s[i]}?>?'a'?&&?${s[i]}?<?'z'?]];?then?echo?${s[i]}?is?a?lowercase?letter;?else?echo?${s[i]}?is?not?a?letter;?fi;?let?i++;?done
b?is?a?lowercase?letter
d?is?a?lowercase?letter
3?is?not?a?letter
user?@?host?:?~?$?^C
注意:在bash中,數(shù)組下標(biāo)是從0開始的。所以上例中數(shù)組下標(biāo)變量i的初始值為0。
(二)實(shí)例2
定義字符串s=abcd0,初始化循環(huán)變量i,然后從i開始截取字符串s值并輸出,直到截取的字符串為0時結(jié)束循環(huán)。
1.在bash命令行中執(zhí)行成功
[csdn ~]$ s=abcd0; i=0; while [[ ${s:i} != '0' ]] ; do echo ${s:i}; let i++; done?
abcd0
bcd0
cd0
d0
[csdn ~]$?
2.在zsh中執(zhí)行不成功
(1)在zsh命令行執(zhí)行不成功
# csdn @ edu in ~ [13:03:22]?
$ s=abcd0; i=1; while [[ ${s:i} != '0' ]] ; do echo ${s:i}; let i++; done
zsh: unrecognized modifier `i'# csdn @ edu in ~ [13:03:26] C:1
$ s=abcd0; i=1; while [[ ${s:$i} != '0' ]] ; do echo ${s:i}; let i++; done
zsh: unrecognized modifier `i'# csdn @ edu in ~ [13:03:32] C:1
$ s=abcd0; i=1; while [[ ${ s:${i} } != '0' ]] ; do echo ${s:i}; let i++; done
zsh: bad substitution# csdn @ edu in ~ [13:03:54] C:1
$ s=abcd0; i=1; while [[ ${s:${i}} != '0' ]] ; do echo ${s:i}; let i++; done?
zsh: unrecognized modifier `i'# csdn @ edu in ~ [13:04:01] C:1
$ s=abcd0; i=1; while (( ${s:${i}} != '0' )) ; do echo ${s:i}; let i++; done
zsh: bad math expression: operand expected at `'0' '# csdn @ edu in ~ [13:04:11]?
$ s=abcd0; i=1; while (( ${s:i} != '0' )) ; do echo ${s:i}; let i++; done?
zsh: unrecognized modifier `i'# csdn @ edu in ~ [13:04:22]?
$ s=abcd0; i=1; while (( ${s:$i} != '0' )) ; do echo ${s:i}; let i++; done
zsh: bad math expression: operand expected at `'0' '# csdn @ edu in ~ [13:04:30]?
$?
(2)寫入腳本文件在zsh中執(zhí)行出錯
# csdn @ edu in ~ [14:50:09] C:126
$ echo '#!/bin/zsh' > a.sh# csdn @ edu in ~ [14:50:51]?
$ echo i=1 >> a.sh# csdn @ edu in ~ [14:50:51]?
$ echo 'while [[ ${s:i} != '0' ]]' >> a.sh?# csdn @ edu in ~ [14:50:51]?
$ echo do ?>> a.sh# csdn @ edu in ~ [14:50:51]?
$ echo 'echo ${#s:i}' ?>> a.sh# csdn @ edu in ~ [14:50:51]?
$ echo 'let i++;' ? >> a.sh# csdn @ edu in ~ [14:50:51]?
$ echo done >> a.sh?# csdn @ edu in ~ [14:50:53]?
$ cat a.sh
#!/bin/zsh
i=1
while [[ ${s:i} != 0 ]]
do
echo ${#s:i}
let i++;
done# csdn @ edu in ~ [14:50:57]?
$ . ./a.sh
./a.sh:3: unrecognized modifier `i'
我們利用echo?配合輸出重定向創(chuàng)建了腳本文件a.sh,但腳本文件a.sh也沒運(yùn)行成功。
三、無限循環(huán)
我們用無限循環(huán)每隔30秒顯示提示信息?press Ctrl+C to exit,在用戶按下Ctrl+C后結(jié)束循環(huán)。?
(一)用true作為循環(huán)表達(dá)式
1.在zsh命令行執(zhí)行
# csdn @ edu in ~ [15:06:21]?
$ ?while true; do echo 'press Ctrl+C to exit'; sleep 30s; done
press Ctrl+C to exit
press Ctrl+C to exit
press Ctrl+C to exit
press Ctrl+C to exit
^C% ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# csdn @ edu in ~ [15:08:23] C:130
$?
2.在bash命令行執(zhí)行
[csdn ~]$ while true; do echo 'press Ctrl+C to exit'; sleep 30s; done
press Ctrl+C to exit
press Ctrl+C to exit
^C
[csdn ~]$?
在上面的例子中,為了避免提示信息?press Ctrl+C to exit?刷屏,我們使用了命令:
sleep 30s
來等待30秒鐘。
(二)使用冒號(:)?作為循環(huán)表達(dá)式
1.冒號(:)表達(dá)式或命令的作用
在Linux中,冒號(:)?有很多種用法,其中之一是作為空表達(dá)式或空命令,返回值為0。
我們可以創(chuàng)建一個包含以下兩條命令的腳本文件a.sh?來觀察冒號(:)作為空命令執(zhí)行時的返回值(保存在$?中)。
:
echo $?
腳本文件創(chuàng)建和執(zhí)行情況:
# csdn @ edu in ~ [15:22:38]?
$ echo ':' > a.sh ? ? ?# csdn @ edu in ~ [15:23:20]?
$ echo 'echo $?'>> a.sh# csdn @ edu in ~ [15:23:27]?
$ cat a.sh
:
echo $?# csdn @ edu in ~ [15:23:33]?
$ . ./a.sh ? ? ? ? ? ??
0# csdn @ edu in ~ [15:23:36]?
$?
2.在zsh命令行執(zhí)行
# csdn @ edu in ~ [15:08:23] C:130
$ ?while : ; do echo 'press Ctrl+C to exit'; sleep 30s; done
press Ctrl+C to exit
press Ctrl+C to exit
press Ctrl+C to exit
^C% ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# csdn @ edu in ~ [15:12:29] C:130
3.在bash命令行執(zhí)行
# csdn @ edu in ~ [15:13:11] C:130
$ exec bash
[csdn ~]$ while : ; do echo 'press Ctrl+C to exit'; sleep 30s; done
press Ctrl+C to exit
press Ctrl+C to exit
^C
[csdn ~]$?
文章來源:http://www.zghlxwxcb.cn/news/detail-738280.html
一般推薦使用冒號(:)?作為循環(huán)表達(dá)式的無限循環(huán),因?yàn)槭褂妹疤枺?)命令系統(tǒng)資源開銷更小。文章來源地址http://www.zghlxwxcb.cn/news/detail-738280.html
到了這里,關(guān)于Linux shell編程學(xué)習(xí)筆記18:while循環(huán)語句的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!