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

  1. break用于跳出当前循环

示例一:

#!/bin/bash
for (( flag=0; flag <= 10; flag++ ))
do
    if (( $flag == 5 ))
    then
        break
    fi
    echo $flag
done

以上当flag的值为5的时候,退出循环。输出结果为0-4的值。

  1. 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

...

  1. 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的输入参数以及接收用户输入。大家可以举一反三,结合之前所学的基础知识,可以写一些小的脚本应用了。

posted @ 2021-03-31 23:26  白色的番茄  阅读(355)  评论(0编辑  收藏  举报