Shell 流程控制
if/elif/else、case、for、while、until、break/continue。
Key Pointsif 判断的是命令的退出码;case 适合多分支字符串匹配;for 遍历列表,while 适合读文件与轮询。
if / elif / else
Bash
score=85
if [ "$score" -ge 90 ]; then
echo "A"
elif [ "$score" -ge 60 ]; then
echo "B"
else
echo "F"
fiOutput
Bif takes a command and branches on its exit status, not a boolean. That is why if grep -q foo file; then works without [ ].
case
Bash
action="start"
case "$action" in
start|run) echo "starting" ;;
stop) echo "stopping" ;;
restart) echo "restarting" ;;
*) echo "unknown: $action" ;;
esacOutput
startingfor
Bash
for i in 1 2 3; do
echo "i=$i"
done
for f in a.txt b.txt; do
echo "file: $f"
done
for n in $(seq 1 3); do printf "%s " "$n"; done; echoOutput
i=1
i=2
i=3
file: a.txt
file: b.txt
1 2 3 while 与 until
Bash
i=1
while [ "$i" -le 3 ]; do
echo "while $i"
i=$((i + 1))
done
j=1
until [ "$j" -gt 2 ]; do
echo "until $j"
j=$((j + 1))
doneOutput
while 1
while 2
while 3
until 1
until 2读文件
Bash
while IFS= read -r line; do
echo "line: $line"
done < <(printf 'a\nb\n')Output
line: a
line: bwhile read in a pipeline runs in a subshell, so variables set inside are lost. Use < <(...) or done < file to keep them.break 与 continue
Bash
for i in 1 2 3 4; do
[ "$i" -eq 2 ] && continue
[ "$i" -eq 4 ] && break
echo "keep $i"
doneOutput
keep 1
keep 3if / elif / else
Bash
score=85
if [ "$score" -ge 90 ]; then
echo "A"
elif [ "$score" -ge 60 ]; then
echo "B"
else
echo "F"
fiOutput
Bif 后面跟的是命令,判断依据是它的退出码,不是布尔值。所以 if grep -q foo file; then 是合法的,不需要套 [ ]。
case
Bash
action="start"
case "$action" in
start|run) echo "starting" ;;
stop) echo "stopping" ;;
restart) echo "restarting" ;;
*) echo "unknown: $action" ;;
esacOutput
startingfor
Bash
for i in 1 2 3; do
echo "i=$i"
done
for f in a.txt b.txt; do
echo "file: $f"
done
for n in $(seq 1 3); do printf "%s " "$n"; done; echoOutput
i=1
i=2
i=3
file: a.txt
file: b.txt
1 2 3 while 与 until
Bash
i=1
while [ "$i" -le 3 ]; do
echo "while $i"
i=$((i + 1))
done
j=1
until [ "$j" -gt 2 ]; do
echo "until $j"
j=$((j + 1))
doneOutput
while 1
while 2
while 3
until 1
until 2读文件
Bash
while IFS= read -r line; do
echo "line: $line"
done < <(printf 'a\nb\n')Output
line: a
line: bwhile read 配合管道会开子 shell,循环里改的变量出不来。用 < <(...)(进程替换)或 while ... done < file 才能保留变量。break 与 continue
Bash
for i in 1 2 3 4; do
[ "$i" -eq 2 ] && continue
[ "$i" -eq 4 ] && break
echo "keep $i"
doneOutput
keep 1
keep 3