第二十六章26-启动一个项目
通过练习小项目,我们在反复的练习中学习shell功能
本章最后我们将编写一个报告生成器shell26.1 第一阶段:最小的文档
本节内容:其实就是在linux环境下,编写脚本,它的标准输出为一个html网页。
第一步:在bin目录下建立shell脚本,echo html 标签
第二步:shell脚本 的 标准输出 存到一个html文本中26.2 第二阶段:添加一点儿数据
添加些数据,让页面更丰满26.3 变量和常量
这部分内容与 前端JS语句很类似,
title="a sentence"
使用 $title 等价于 字符串“a sentence”
实验例子: mv file1 ${fileanme}1输出文本可以使用echo,也可以使用I/O重定向形式
token是一个指示嵌入文本结束的字符串。
command << token
实验例子: cat << _EOF_
"BALABALA"
'BALABALA'
_EOF_
注意token必须在一行中单独出现,且行末无空格
第二十七章27-自顶向下设计
什么是自顶向下设计?
程序变得庞大和复杂后,维护工作会很难进行,需要把任务细化成细小的任务。
由大变小的过程叫自顶向下设计。27.1 局部变量
在函数内部使用
第一次出现时 用 local + var_name 声明#!/bin/bash
# local-vars: script to demonstrate local variables
foo=0 # global variable foo
funct_1(){
local foo # variable foo local to funct_1
foo=1
echo "funct_1: foo = $foo"
}
funct_2(){
local foo # variable foo lacal to funct_2
foo=2
echo "funct_2: foo = $foo"
}
echo "global: foo = $foo"
funct_1
echo "global: foo = $foo"
funct_2
echo "global: foo = $foo"结果:
global: foo = 0
funct_1: foo = 1
global: foo = 0
funct_2: foo = 2
global: foo = 0
27.2 保存脚本运行
经常测试脚本,如果发现出现问题,很可能是最新的修改照成的。if分支结构可以让脚本适应不同的执行环境,
如:根据用户的权限不同,执行不同的操作。x=5
if [ $x = 5 ]; then
echo "x equals 5."
else
echo "x does not equal 5."
fi[seven@localhost ~]$ touch liucheng
[seven@localhost ~]$ vi liucheng
[seven@localhost ~]$ bash liucheng
x equals 5.语法结构为:
if commands; then
commands
[elif commands; then
commands...]
[else
commands]
fi
第二十八章28-流程控制(if分支结构)
在脚本中基于测试条件结果,来改变内在的运行方向。28.1 退出状态
当命令执行完毕,命令会给系统发送一个值,叫退出状态(0-255)
当if之后跟随多个命令,将计算列表中的最后一个命令。
状态码0为运行成功,其他状态码都表示不成功。[seven@localhost ~]$ ls -d /usr/bin
/usr/bin
[seven@localhost ~]$ echo $?
0
[seven@localhost ~]$ ls -d /bin/usr
ls: 无法访问/bin/usr: 没有那个文件或目录
[seven@localhost ~]$ echo $?
2
[seven@localhost ~]$ true
[seven@localhost ~]$ echo $?
0
[seven@localhost ~]$ false
[seven@localhost ~]$ echo $?
1当if之后跟随多个命令,将计算列表中的最后一个命令
[seven@localhost ~]$ if false; true; then echo "It's true."; fi
It's true. '28.2 测试
test命令执行各种各样的检测与比较
test expression 或 [expression]文件表达式(表达式用来计算文件状态)
实验例子:
FILE=~/.bashrc
if [ -x "$FILE" ]; then
echo "$FILE is executable/searchable."
fi字符串表达式
大于、小于、单等号、双等号、 -z 字符串为空
实验例子:
ANSWER=maybe
if [ -z "$ANSWER" ]; then
echo "There is no answer." >&2
exit 1
fi
if [ "$ANSWER" = "yes" ]; then
echo "The answer is YES."
elif [ "$ANSWER" = "no" ]; then
echo "The answer is MAYBE."
else
echo "The answer is UNKNOWN."
fi整形表达式
大于(-gt)、小于(-lt)、等于(-eq)
实验例子:
INT=-5
if [ $INT -gt 0 ]; then
echo "INT is gt 0"
elif [ $INT -lt 0 ]; then
echo "INT is lt 0"
elif [ $INT -eq 0 ]; then
echo "INT is eq 0"
fi28.3 更现代的测试版本
[[ expression ]] 是加强版的 test 命令,
重要用法,新的字符串表达式: string1 =~ regex
通过应用正则表达式,限制INT的值只是字符串
实验例子:
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
if [ $INT -eq 0 ]; then
echo "INT is zero"
else
echo "INT isn't 0"
fi
fi[[]] 添加的另一个功能是 == 操作支持 类型匹配
实验例子:
[seven@localhost ~]$ FILE=foo.bar
[seven@localhost ~]$ if [[ $FILE == foo.* ]]; then
> echo "$FILE matches pattern 'foo.*'"
> fi
foo.bar matches pattern 'foo.*'28.4 (())为整数设计
[[]] 是复合命令,(()) 也是复合命令,有利于操作整数。
当算式 结果非零 结果为真实验例子:
INT=-5
if (( $INT == 0 )); then
echo "INT is 0"
elif (( $INT < 0 )); then
echo "INT is lt 0"
elif (( $INT > 0 )); then
echo "INT is gt 0"
fi
28.5 结合表达式
and(测试 -a) 、or(测试 -o) 、not(测试 !)test表达式中例子:
if [[ INT -ge MIN_VAL && INT -le MAX_VAL ]]; then
echo "balabala"
也可以使用圆括号,为的是分组。如果不使用括号,
那么否定只应用于第一个表达式,而不是两个组合的表达式。
测试表达式中的例子:
if [ ! \( INT -ge MIN_VAL -a INT -le MAX_VAL \) ]; then
echo "balabala"28.6 控制操作符:分支的另一种方法
bash支持两种可以执行分支任务的控制操作符。&&、||28.7 总结
上文提到,分支语句可以根据用户权限不同,执行不同语句
实验例子:
if [[$(id -u) -eq 0]]; then
echo "super root!"
第二十九章29-读取键盘输入
有些程序需要与用户交互,本章将学习让程序可以接受用户的输入29.1 read(从标准输入读取数值)
使用 -n 选项,删除输出结果末尾的 换行符,
通常用于让用户在显示文本的同一行输入。
echo -n "sentence..."
使用 -p 选项, 显示提示信息
read -p "enter one or more vajlues > "使用 -t -s 选项, 分别是 规定时间内输入 与 不在屏幕显示字符
read 命令 可以跟随多个变量
read var1 var2 var3 var4 var5
如果用户输入过少,后面的变量为空字符串
如果用户输入过多,最后的变量为字符串数组
如果read命令 后面 不跟随变量,输入将存于REPLY中
echo " REPLY = '$REPLY' "IFS(内部字符分隔符)
我们读取 /etc/passwd文件,读出 某个用户名的资料
FILE=/etc/passwd
file_info=$(grep "^$user_name:" $FILE) # 只读某个用户名
IFS=":" read user pw uid gid name home shell <<< "$file_info"
这里的 <<< 操作符 指示一个here 字符串,它就像一个here文档。不能使用管道read
read命令接受标准输入,在bash中,管道线会创建子shell,
read命令将在子shell执行,$REPLY 只存在于子shell中。所以我们这里用here字符串。29.2 校正输入
程序每次接受数据时,进行检查数值。
可以使用shell函数、[[]]、(())、正则表达式29.3 菜单
从逻辑上讲,脚本分为两部分,第一部分显示菜单和用户输入
第二部分确认用户反馈。exit被用来阻止脚本执行不必要的代码,
通常出现多个exit代码是一个坏逻辑,它让程序逻辑难以理解。第三十章30-流程控制(while/until 循环)
前面开发的程序只能执行单一的选择,然后终止,
本章开发的程序可以重复显示,直用户选择退出。30.1 循环
命令while,计算test命令的退出状态,退出状态为零继续执行,until恰相反
while commands; do
commands;
done
分割线——————————
until commands; do
commands;
done
30.2 跳出循环
continue; break;
30.3 使用循环读取文件
\ :表示此行接下一行
< : 重定向操作符,从文件读取字段#!/bin/bash
# while-read: read lines from a file
while read distro version release; do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
$distro \
$version \
$release
done < distros.txt