Shell 学习笔记 0x05

Shell 学习笔记 0x05

RayAlto OP

1. 分支的另一种形式

Shell 也有和 C 系列语言相似的 &&, || 等符号,可以用来实现更复杂的功能:

1
2
3
[ -d temp ] || mkdir temp           # 如果 temp 目录不存在则创建
[ -x bin ] || exit 1 # 如果 bin 不可被当前用户执行则异常退出
[ -s file ] && cat /dev/null > file # 如果 file 不为空则清空内容

2. 读取标准输入

1
2
read -ep 'input: ' foo
echo ${foo}

运行:

1
2
3
$ ./test.sh
input: bye world
bye world

一些有用的选项:

选项作用
-a array把输入放进数组 array 里,索引从零开始
-d delimiterdelimiter 的第一个字符作为输入结束的指示,否则默认为换行符
-e使用 readline 处理输入,使行为与命令行相同
-n num读取 num 个字符,而不是等待完整的一行
-p prompt设置提示信息
-rRaw mode ,不把 \ 当作转义字符
-sSilent mode ,模拟密码输入,不现实用户的输入
-t seconds等待输入超过 seconds 则超时退出,返回非零值
-u fd从文件描述符 fd 读取输入

3. while

Shell 的 while 语法是:

1
2
3
4
5
while commands; do
commands
done

while commands; do commands; done

比如打印五次 “bye world” :

1
2
3
4
while (( i < 5 )); do
echo "bye world"
i=$(( i + 1 ))
done

当然也有 continue/break 来进行更复杂的控制:

1
2
3
4
5
6
7
8
9
10
11
12
while (( i < 5 )); do
i=$(( i + 1 ))
if (( i == 2 )); then
echo foo
continue
fi
if (( i == 4 )); then
echo bar
break
fi
echo ${i}
done

输出:

1
2
3
4
1
foo
3
bar

4. until

Shell 还有 until 关键字,语法为:

1
2
3
4
5
until commands; do
commands
done

until commands; do commands; done

行为是直到 until 后面的 commands 返回值为 0 ,反复执行 do 后面的 commands ,比如:

1
2
3
4
until (( i == 5 )); do
echo "bye world"
i=$(( i + 1 ))
done

也会输出五次 “bye world”

5. 为循环进行 I/O 重定向

比如用 < 放在 done 后面:

1
2
3
while commands; do
commands
done < file

或者 | 放在开头:

1
2
3
cat file | while commands; do
commands
done

6. case

Shell 当然也有类似 switch 的语法( pattern 支持通配符):

1
2
3
case word in
[pattern [| pattern]...) commands ;;]...
esac

比如:

1
2
3
4
5
6
read choice
case $choice in
0) echo "0" ;;
1 | 2) echo "1 || 2" ;;
*) echo "others" ;;
esac

C 系列语言的 switch 的每个 case 最后都要写 break ,否则会继续运行下一个 case ,在 Shell 中 ;; 会自动离开 case 块

Shell 的 case 还有一个更独特的特性,用 ;;& 结尾会进行多次匹配,比如:

1
2
3
4
5
6
choice=114514
case $choice in
114*) echo ok ;;&
*514) echo ok ;;
*) echo not ok ;;
esac

会输出两次 ok