1. shell编程基础概念入门
shell 编程
如今 , 不会shell编程就不能说自己会linux , 说起来似乎shell编程很屌啊 ,然而不用担心 , 其实shell编程很简单
背景
什么是shell编程
高大上的解释 , 往往让人摸不着头脑 。 一句话概括就是: shell编程就是对一堆linux 命令的逻辑化处理。
为什么要会shell编程
举个简单的例子 , 我们做goweb 开发的,在以前要在本地将程序打包 , 然后部署到远程服务器(抛开现在的ci , 原始的方法),我们以前的做法通常会经历如下几个步骤:
-
拉取最新代码(git pull)
-
编译打包
-
上传并部署到远程服务器
每次打包都要经历这个阶段 , 效率低又烦躁, 而此时 , 我们可以编写一个shell脚本,然后每次只需要运行一下这个shell脚本
, 即可以实现打包部署这一系列动作 , 彻底解放双手 , 多好
入门
第一个shell 程序
#!/bin/bash
#第一个shell小程序
echo hello world!
以上, 我们第一个shell小程序就完成了 , 结果当然是输出我们熟悉的hello world
第一行表示我们选择使用bash shell
shell中#符号表示注释。 shell 的第一个比较特殊 , 一般都会以#!开始来指定使用的shell类型 , 在linux 中 。 除了bash shell 以外 , 还有很多版本的shell , 例如zsh , dash 等。。不会bash shell还是我使用最多的 。
第二行以#符号开始 ,表示本行是注释 , 运行的时候是不会运行本行的 。
第三行中echo 是linux 中的输出命令 , 该行的意思很明显的就是输出hello world !
运行第一个shell程序
新创建一个文件(hello_world.sh) , 然后将以上代码赋值到此文件中, 然后需要赋予此文件的可执行权限
chmod +x hello_world.sh
最后执行:
./hello_world.sh
在linux 中, 后缀名几乎是可以任意的或者没有后缀名 , 一般讲shell 保存为xx.sh 是为了看起来更直观。 如果直接执行hello_world.sh ,这时会默认从$PATH环境变量中去寻找, 这时 , 由于我们为将此文件配置在环境变量中, 因此会找不到 , 所以 , 我们用了”.“ 这个符号, 表示从当前目录找 。除了以上执行方法, 我们还可以直接指定shell来运行:
/bin/sh hello_world.sh
这儿我们指定用了/bin/sh 来执行, 这时hello_world.sh 中指定的/bin/bash将不会生效
变量
编程岂能没有变量?对吧?
shell编程中分为两种变量 , 第一种是我们自己定义的变量(子定义变量), 第二种是linux 已定义的环境变量(环境变量, 例如:$PATH,$HOME等... 这类变量我们可以直接使用)。
#!/bin/bash
#使用环境变量
echo $PATH
#自定义变量hello
hello="hello world"
echo $hello
以上演示了自定义变量和系统环境变量的用法 , 使用很简单 , 就是使用$符号加上变量名就行了 , 记住:定义变量不用个$符号, 使用变量要加$就行了
在第5行中 , 我们在定义变量时 , 使用了双引号 , 在shell编程中 , 如果变量出现空格或者引号, 那么必须加引号 , 否则就可以省略
还有一点需要注意 , 定义变量的时候 , ”=“左右千万不要有空格啊
将linux 命令执行结果赋值给变量
#!/bin/bash
path=$(pwd)
files=`ls -al`
echo current path: $path
echo files: $files
以上2行和第3行分别演示了两种方式来讲linux 命令执行结果保存到变量
第2行将pwd 执行结果(当前所在目录)赋值给path变量
第2行将ls -al 命令执行结果 (列出当前目录下所有的文件及文件夹)赋值给变量
注意:第2行的符号不是单引号 , 是键盘上”~“ 这个按键
好啦 , 到此对shell 编程已经有初步认识了 , 也会使用变量了 , 到此, 看起来shell 编程是不是很简单, 没有错 , 其实真的旧这么一回事。
基本数据类型运算
操作符
符号 | 语义 | 描述 |
---|---|---|
+ | 加 | 10+10 , 结果20 |
- | 减 | 10-3 , 结果为7 |
* | 乘 | 10*2,结果为20 |
/ | 除 | 10/3 ,结果为3(去整数) |
% | 求余 | 10%3 ,结果为1(取余数) |
== | 判断是否相等 | 两数不等返回1 ,否则0 |
!= | 判断是否不等 | 两数不等返回1 , 否则0 |
> | 大于 | 前者大于后者返回1 , 否则0 |
>= | 大于或等于 | 前者大于或等于后者返回1 , 否则0 |
< | 小于 | 前者小于后者返回1 , 否则0 |
<= | 小于或等于 | 前者小于或等于后者返回1 , 否则0 |
上述操作符与其他语言相比 , 并无特殊之处
在shell 中 , 对于基本数据类型的运算主要分为两种 , 整数运算和浮点数(小数)运算. 下面就分别来看看这两种运算 :
整数运算
在shell 中, 有两种方式能实现整数运算 , 一种是使用expr命令 , 另外一种是通过方括号
expr
#!/bin/bash
#输出13
expr 10+3
#输出10+3
expr 10+3
#输出7
expr 10 - 3
#输出30
expr 10 \* 3
#输出3
expr 10 / 3
#输出1
expr 10 % 3
#将计算结果赋值给变量
num1=$(expr 10 % 3)
#将计算结果赋值给变量
num2=`expr 10 % 3`
注意:1.在以上乘法(*)中,我们用了反斜线(\)来转义, 不然会报错。2.运算符前后必须还有空格 , 否则会被直接当做字符串返回 。3.如果要将计算结果保存到变量 , 就需要用到我们上篇文章讲到的那两种方式($()或``)来替换命令了。
这种种迹象无不让人吐槽啊 。 幸好还有一种实现方式 , 那就是接下来要看的方括号
方括号($[])
#!/bin/bash
num1=10
num2=3
#输出num1 + num2=13
echo "num1 + num2=$[$num1 + $num2]"
#输出num1+num2=13
echo "num1+num2=$[$num1+$num2]"
#输出num1 - num2=7
echo "num1 - num2=$[$num1 - $num2]"
#输出num1 * num2=30
echo "num1 * num2=$[$num1 * $num2]"
#输出num1 > num2=1
echo "num1 > num2=$[$num1 > $num2]"
#输出num1 < num2=0
echo "num1 < num2=$[$num1 < $num2]"
#将运算结果赋值给变量,输出num3=3
num3=$[$num1 / $num2]
echo "num3=$num3"
看了这种运算 , 在回看expr , 是不是觉得要升天 , 终于正常了。expr 的那几个注意事项 , 在这儿都不算事儿。所以 , 如果要图简单 , 还是用这种方式吧 。
浮点运算
在shell 中 , 做浮点运算一般是用base 的计算器(bc)。 在shell 脚本中 , 一般我们的使用方法是:
variable=$(echo "options; expression" | bc)
options是bc的协议选项, 例如:可以通过scale去设置保留的小数位数 , 具体有哪些参数 ,可以man bc 进行查看 expression 就是我们具体的表达式, 例如 10 * 3
“|” 这个符号 , 对于熟悉linux系统的人来说 , 这个再熟悉不过了 , 它叫做管道 , 之所以会叫做管道 , 其实很形象, 你可以把它看作一根水管吗水管一头接入前一个命令的返回结果 , 一头接入下一个命令 。表示将前一个命令的执行结果作为后一个命令的参数输入 。 以上 , 表示将我们的表达式作为bc的参数输入。
#!/bin/bash
#表示 10/3, 保留2位小数 , 将结果赋值给了num, 输出3.33
num=$(echo "scale=2;10 / 3" | bc)
echo $num
条件选择
在条件选择语句中国 , 主要包含以下几种写法
if-then语句
if command
then
commands
fi
吃瓜群众表示一脸懵逼: if语句后面接的是命令 , 我们其他编程语言中 , 这儿都是接返回布尔值(true,false)的表达式。
那么到底是怎么回事呢?
在shell 脚本的if其实是根据后面的命令的退出状态来判断是否执行then 后面的语句的 。
关于退出状态吗, 你只需要记住:正常退出(命令执行正常)的状态码是0 , 非正常退出的状态码不是0(有不少)
以上语句的语义为: 如果if后面的命令执行正常(状态码0), 那么久执行then后面的语句 , 否则不执行, fi代表if语句的结束
#!/bin/bash
#这儿由于pwd是linux内置的命令, 因此执行后会正常退出(状态码0),所以会执行then中的语句
#如果此处替换为一个不存在的命令(例如:pw) , 那么就会飞正常退出, 不会执行then中的语句
if pwd
then
echo 执行then里面的语句
fi
if-then还可以简写为
if command;then
commands
fi
因此 , 以上代码还可以写成以下:
#!/bin/bash
if pwd;then
echo 执行then里面的语句
fi
以上,如果我要判断处理异常退出(状态码非0)情况,该怎么办?
别着急: else 来帮你。
if-then-else语句
if command
then
commands
else
commands
fi
与if-then语句相比,这回多了个else语句,else语句用来判断if后面的命令非正常退出的情况。
#!/bin/bash
if pwd
then
echo 正常退出
else
echo 非正常退出
fi
甚至,我们还可以变形写出更多的else:
if command1
then
commands
elif
command2
then
command3
fi
但是上面就只能根据退出状态码判断,不能写表达式,你还让我怎么写? 我各个编程语言直接吊打你!
不要慌,客官,请接着往下看:
test命令
test命令用于if-then或者if-then-else语句中,主要用于判断列出的条件是否成立,如果成立,就会退出并返回退出状态码0,否则返回非0。
这意味着我们可以通过test命令来写表达式命令了。不过,对于已习惯其它编程语言的程序猿们(没学过的除外),不要高兴得太早,前方有坑,至于是什么坑,待会儿就能看到。
先看看test命令的基本用法吧:
直接用:
test condition
结合if-then语句用
if test condition
then
commands
fi
结合if-then-else语句用
if test condition
then
commands
else
commands
fi
条件成立就执行then语句,否则else语句。
test命令只能判断一下三类条件:
- 数值比较
- 字符串比较
- 文件比较
数值比较
比较 | 描述 |
---|---|
n1 -eq n2 | 判断n1是否等于n2 |
n1 -ge n2 | 判断n1是否大于或等于n2 |
n1 -gt n2 | 判断n1是否大于n2 |
n1 -le n2 | 判断n1是否小于或等于n2 |
n1 -lt n2 | 判断n1是否小于n2 |
n1 -ne n2 | 判断n1是否不等于n2 |
特别提醒: 以上表格不用你去记住,在命令行下面, 执行man test就能看到这些了。后面的对与另外两种比较的同理
#!/bin/bash
num1=100
num2=200
if test $num1 -eq $num2
then
echo num1等于num2
else
echo num2不等于num2
fi
好好的标准的数学比较符号不能使用,难道非得写这种文本形式?是不是觉得很别扭?
不着急,还有替代方案:
使用双括号
双括号命令允许你在比较过程中使用高级数学表达式。关键是使用双括号,咱就可以用数学比较符号啦(等于==, 大于>, 小于< 等等都能使用啦)。
使用方法:
(( expression ))
注意:括号里面两边都需要有空格
#!/bin/bash
num1=100
num2=200
if (( num1 > num2 ))
then
echo "num1 > num2"
else
echo "num2 <= num2"
字符串比较
比较 | 描述 |
---|---|
str1 = str2 | 判断str1是否与str2相同 |
str1 != str2 | 判断str1是否与str2不相同 |
str1 < str2 | 判断str1是否比str2小(根据ASCII) |
str1 > str2 | 判断str1是否比str2大(根据ASCII) |
-n str1 | 判断str1的长度是否非0 |
-z str1 | 判断str1的长度是否为0 |
程序猿们,要骂的就尽情释放吧。我反正是骂了。
test命令和测试表达式使用标准的数学比较符号来表示字符串比较,而用文本代码来表 示数值比较。这与其它语言相比都不一样。
#!/bin/bash
var1=test
var2=Test
if test $var1 = $str2
then
echo 相等
else
echo 不相等
fi
注意,在使用大于(>)或小于(<)符号时,需要转义(>)(<),不然会把这两种符号时别为重定向(后面文章才会讲到)。
吐槽模式开启:我要用个比较符号,还要转义,很蛋疼的设计!
不要慌,大招一般都在后面:
使用双方括号
双方括号命令提供了针对字符串比较的高级特性。它不仅解决了使用test所带来的一系列毛病,还提供了一些test命令所没有的高级用法。双方括号命令的格式如下:
[[ expression ]]
注意,可能有些shell不支持此种写法。不过bash完美支持。以上写法注意括号内两边都有空格。
#!/bin/bash
var1=test
var2=Test
if [[ $test < $test2 ]]
then
echo "test1 < test2"
else
echo "test1 >= test2"
fi
这下终于不用转义了。
文件比较
对于文件的比较,其实跟上面差不多,都是用test命令。由于篇幅有限,我这儿就不多写了。通过man test命令可以看到具体的用法。
case语句
在使用if-then-else语句中,如果碰到条件很多的情况,如下:
#!/bin/bash
num=3
if (( $num == 1 ))
then
echo "num=1"
elif (( $num == 2 ))
then
echo "num=2"
elif (( $num == 3 ))
then
echo "num=3"
elif (( $num == 4 ))
then
echo "num=4"
fi
如果再多点条件,看起来是不是很多?
此时,其实还有一种替代方案,那就是使用case.
case variable in
pattern1 | pattern2) commands1;; pattern3) commands2;;
*) default commands;;
esac
将以上代码替换为case:
#!/bin/bash
case $num in
1)
echo "num=1";;
2)
echo "num=2";;
3)
echo "num=3";;
4)
echo "num=4";;
*)
echo "defaul";;
esac
上面主要介绍:条件语句 , shell中的条件语句与其他编程语言相比有不小的区别 , 最大的区别就在于条件语句后接的是命令 ,不是布尔值 , 是根据命令执行退出的状态码来决定是否进入then语句的 ,这点需要牢记
接下来本篇就来学习循环语句。在shell中,循环是通过for, while, until命令来实现的。下面就分别来看看吧。
for
for循环有两种形式:
for-in语句
基本格式如下:
for var in list
do
commands
done
list代表要循环的值,在每次循环的时候,会把当前的值赋值给var(变量名而已,随意定), 这样在循环体中就可以直接通过$var获取当前值了。
先来一个例子吧:
#!/bin/bash
for str in a b c d e
do
echo $str
done
以上会根据空格将abcde分割,然后依次输出出来。
如果以上例子不是以空格分割,而是以逗号(,)分割呢?
#!/bin/bash
list="a,b,c,d,e"
for str in $list
do
echo $str
done
结果输出a,b,c,d,e
造成这个结果的原因是:for...in循环默认是循环一组通过空格或制表符(tab键)或换行符(Enter键)分割的值。这个其实是由内部字段分隔符配置的,它是由系统环境变量IFS定义的。当然,既然是由环境变量定义的,那当然也就能修改啊。
修改IFS值
#!/bin/bash
#定义一个变量oldIFS保存未修改前的IFS的值
oldIFS=$IFS
#修改IFS值,以逗号为分隔符
IFS=$','
list=a,b,c,d,e
list2="a b c d e"
for var in $list
do
echo $var
done
for var2 in $list2
do
echo $var2
done
#还原IFS的值
IFS=$oldIFS
以上第一个循环会分别输出abcde几个值。而第二个循环会输出a b c d e(即未处理)。因为我们把IFS的值设置为逗号了, 当然,不一定要是逗号,想设置什么,你说了算!
C语言风格的for循环
bash中c语言风格的for循环遵循如下格式:
for (( variable assignment ; condition ; iteration process ))
一个例子足以说明:
#!/bin/bash
for (( i = 0; i <= 10; i++ ))
do
echo $i
done
上面例子循环11次,从0到10依次输出。稍微有过编程基础的都对此应该很熟悉。就不做详细阐述了。
while循环
如果你习惯了其它语言的while循环,那么到这儿你又会发现这个while循环有点变态了。与其它编程语言while的不同在于:在bash中的while语句,看起来似乎是结合了if-then语句(参考上一篇)和for循环语句。其基本格式如下:
while test command
do
other commands
done
与if-then语句一样,后面接test命令,如果test后面的命令的退出状态码为0. 那么就进入循环,执行do后面的逻辑。要注意在do后面的逻辑中写条件,避免死循环。
既然是接test命令,那么一切都可以参考if-then的test
示例一:
#!/bin/bash
flag=0
while test $flag -le 10
do
echo $flag
# 如果没有这句,那么flag的值一直为0,就会无限循环执行
flag=$[$flag + 1]
done
以上判断flag是否大于或者等于10, 如果满足条件,那么输出当前flag的值,然后再将flag的值加1。最终输出的结果为0到10的结果。
结合上一篇文章test的写法,我们还可以将以上示例变形为如下:
示例二:
#!/bin/bash
flag=0
while [ $flag -le 10 ]
do
echo $flag
flag=$[$flag + 1]
done
示例三:
flag=0
while (( $flag <= 10 ))
do
echo $flag
flag=$[$flag + 1]
done
until循环语句
until语句基本格式如下:
until test commands
do
other commands
done
在掌握while循环语句之后, until语句就很简单了。until语句就是与while语句恰好相反, while语句是在test命令退出状态码为0的时候执行循环, 而until语句是在test命令退出状态码不为0的时候执行。
示例:
#!/bin/bash
flag=0
until (( $flag > 10 ))
do
echo $flag
flag=$[ $flag + 1 ]
done
以上输出0到10的值。until后面的条件与上面while例子完全相反。
好啦,到此,我们学完了shell的循环语句啦。不过上面我们写的循环语句都是根据条件执行完毕,如果我们在执行的过程中想退出,该怎么办?接下来就继续看看怎么控制循环语句。
控制循环
与其它编程语言一样,shell是通过break和continue命令来控制循环的。下面就分别来看看二者的基本用法:
break
- break用于跳出当前循环。
示例一:
#!/bin/bash
for (( flag=0; flag <= 10; flag++ ))
do
if (( $flag == 5 ))
then
break
fi
echo $flag
done
以上当flag的值为5的时候,退出循环。输出结果为0-4的值。
- break用于跳出内层循环。
示例二:
#!/bin/bash
flag=0
while (( $flag < 10 ))
do
for (( innerFlag=0; innerFlag < 5; innerFlag++ ))
do
if (( $innerFlag == 2 ))
then
break
fi
echo "innerFlag=$innerFlag"
done
echo "outerFlag=$flag"
done
以上代码在执行内部循环for的时候,当innerFlag值为2的时候就会跳出到外层的while循环, 由于外层循环一直flag都为0, 所以while会成为一个死循环,不停的输出:
...
innerFlag=0
innerFlag=1
outerFlag=0
...
- break用于跳出外层循环
break 可后接数字,用于表示退出当前循环的外层的第几层循环。
示例三:
#!/bin/bash
flag=0
while (( $flag < 10 ))
do
for (( innerFlag=0; innerFlag < 5; innerFlag++ ))
do
if (( $innerFlag == 2 ))
then
# 2表示外面一层循环
break 2
fi
echo "innerFlag=$innerFlag"
done
echo "outerFlag=$flag"
done
与上面例子相比,本例就只是在break后面跟了个数字2,表示退出外面的第一层循环。最终输出:
innerFlag=0
innerFlag=1
continue
continue表示终止当前的一次循环,进入下一次循环,注意,continue后面的语句不会执行。
continue的语法与break一样,因此,就只做一个示例演示啦。
示例:
flag=0
while (( $flag <= 10 ))
do
if (( $flag == 5 ))
then
flag=$[$flag+1]
continue
fi
echo "outerFlag=$flag"
for (( innerFlag=11; innerFlag < 20; innerFlag++ ))
do
if (( $innerFlag == 16 ))
then
flag=$[$flag+1]
continue 2
fi
echo "innerFlag=$innerFlag"
done
done
以上例子: 当for循环中innerFlag的值为16的时候会跳到外层while循环,当外层循环的flag的值为5的时候,会直接跳过本次循环,然后进入下一次循环,因此在输出的结果中,不会出现outerFlag=5的情况。
我们学会了shell的基本语法。在linux的实际操作中,我们经常看到命令会有很多参数,例如:ls -al 等等,那么这个参数是怎么处理的呢? 接下来我们就来看看shell脚本对于用户输入参数的处理。
命令行参数处理
根据参数位置获取参数
bash shell可根据参数位置获取参数。通过 $1 到 $9 获取第1到第9个的命令行参数。\(0**为shell名。如果参数超过9个,那么就只能通过**\){}来获取了, 例如获取第10个参数,那么可以写为${10}。
示例一:
#!/bin/bash
#testinput.sh
echo "file name: $0"
echo "base file name: $(basename $0)"
echo "param1: $1"
echo "param2: ${2}"
运行上面的的shell
./testinput.sh 12 34
最终得到的结果如下:
file name: ./testinput4.sh
base file name: testinput4.sh
param1: 12
param2: 34
成功的得到文件名和命令行输入的参数(命令行参数以空格分隔,如果参数包含了空格,那么久必须添加引号了)
**\(0**默认会获取到当前shell文件的名称,但是,它也包含(./),如果你以完整路径运行,那么这还会包含目录名。因此,上面通过basename命令来获取单纯的文件名\)(basename $0)。
试想一下,假如我们写的shell的这个参数很多,那如果像上面那样一个一个去获取参数,那岂不是要写疯!下面就来看看如何解决这种情况。
读取所有参数
方法一
既然bash shell通过位置可获取参数,那意味着如果我们知道参数的总个数就可以通过循环依次获取参数。那么如何获取参数总个数呢?
在bash shell中通过 $# 可获取参数总数。
示例:(循环获取参数)
#!/bin/bash
for (( index=0; index <= $#; index++ ))
do
echo ${!index}
done
以上示例,我们通过 $# 获取总参数个数。然后通过循环获取每个位置的参数。注意: 按照正常的理解,上面的 ${!index} 应该是 \({\)index}才对, 对吧? 但是,由于\({}内不能再写\)符号,bash shell在这个地方是用了!符号,所以以上才写为了${!index}。
方法二
在bash shell中还可以通过 $* 和 $@ 来获取所有参数。但是这两者之间有着很大的区别:
$* 会将命令行上提供的所有参数当作一个单词保存, 我们得到的值也就相当于是个字符串整体。
$@ 会将命令行上提供的所有参数当作同一字符串中的多个独立的单词。
可能文字看起来描述的不太清楚,那么还是通过示例来看二者的区别吧:
#!/bin/bash
#testinput.sh
var1=$*
var2=$@
echo "var1: $var1"
echo "var2: $var2"
countvar1=1
countvar2=1
for param in "$*"
do
echo "first loop param$countvar1: $param"
countvar1=$[ $countvar1 + 1 ]
done
echo "countvar1: $countvar1"
for param in "$@"
do
echo "second param$countvar2: $param"
countvar2=$[ $countvar2 + 1 ]
done
echo "countvar2: $countvar2"
执行上面的示例:
./testinput.sh 12 34 56 78
上面示例的输出结果为:
var1: 12 34 56 78
var2: 12 34 56 78
param1: 12 34 56 78
countvar1: 2
param1: 12
param2: 34
param3: 56
param4: 78
countvar2: 5
通过上面的结果可见,直接输出看起来二者结果一样,但是通过for循环就可看出二者的区别了。上一篇文章我们讲到for循环会通过IFS定义的值进行分割,因此默认情况下,如果我们上面在for循环处不加引号,那么根据IFS中所定义的空格分割,最终也会导致看不出二者区别。
获得用户输入
单个输入
有时候,我们在shell执行过程中获取用户的输入,以此与用户进行交互。这是通过read命令来实现的。下面就来看看其用法:
示例一:
#!/bin/bash
echo -n "yes or no(y/n)?"
read choice
echo "your choice: $choice"
运行以上示例,首先会输出”yes or no(y/n)?“, 然后会等待用户输入(-n参数表示不换行,因此会在本行等待用户输入),当用户输入后,会把用户输入的值赋值给choice变量, 然后最终输出 “your choice: (你输入的内容)”。
事实上,我们可以不指定read后面的变量名,如果我们不指定, read命令会将它收到的任何数据都放进特殊环境变量REPLY中。如下:
示例二:
#!/bin/bash
echo -n "yes or no(y/n)?"
read
echo "your choice: $REPLY"
以上示例与示例一是等价的。
有时候,我们需要用户输入多个参数,当然,shell是支持一次接受多个参数输入的。
多个输入
示例三:
#!/bin/bash
read -p "what's your name?" first last
echo first: $first
echo last: $last
以上示例首先输出“what's your name?”, 然后在本行等待用户输入(此处用read -p实现以上示例的echo -n + read命令的不换行效果),输入的参数以空格分隔,shell会把输入的值依次赋值给first和last两个变量。如果输入的值过多,假如我输入了3个值,那么shell会把剩下的值都赋值给最后一个变量(即第二三两个的值都会赋值给last变量)。
细想一下,有个问题,假如用户一直不输入,怎么办?一直等待?
超时设置
我们可以通过read -t 来指定超时时间(单位为秒),如果用户在指定时间内没输入,那么read命令就会返回一个非0的状态码。
示例四:
#/bin/bash
if read -t 5 -p "Please enter your name: " name
then
echo "Hello $name"
else
echo "Sorry, timeout! "
fi
运行以上示例,如果超过5秒没输入,那么就会执行else里面的。
小结
本篇简单的介绍了shell的输入参数以及接收用户输入。大家可以举一反三,结合之前所学的基础知识,可以写一些小的脚本应用了。