Shell流程控制 (详解)

for循环

与其他编程语言类似,Shell支持for循环。

#for循环一般格式为:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
#顺序输出字符串中的字符:
for str in 'This is a string'
do
echo $str
done
#输出结果:
This is a string
#遍历数组:
a=("Fdf" "df" "fd")
for str in ${a[@]}
do
echo $str
done
#输出结果:
Fdf
df
fd
#写成一行:
for var in item1 item2 ... itemN; do command1; command2… done

当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。
in列表是可选的,如果不用它,for循环使用命令行的位置参数。

#例如,顺序输出当前列表中的数字:
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
#输出结果:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5

while语句

#while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
while condition
do
command
done
#以下是一个基本的while循环,测试条件是:如果int小于等于5,那么条件返回真。int从0开始,每次循环处理时,int加1。运行上述脚本,返回数字1到5,然后终止。
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
#注意:这里的条件要用双括号,自增要写let,再双引号里面写自增内容
#运行脚本,输出:
1
2
3
4
5
#以上实例使用了 Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按结束循环。
echo -n '请输入你的名字:'
while read FILM
do
echo "是的!这就是你的名字"
done
#运行脚本,输出类似下面:
请输入你的名字:lisa
是的!这就是你的名字

无限循环

#无限循环语法格式:
while :
do
command
done
#或者
while true
do
command
done
#或者
for (( ; ; ))

until循环

until 循循环环执执行行一一系系列列命命令令直直至至条条件件为为 true 时停止。
until 循环与 while 循循环环在在处处理理方方式式上上刚刚好好相相反反。。

#一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
#until 语法格式:
until condition
do
command
done
#condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。
#以下实例我们使用 until 命令来输出 0 ~ 9 的数字:
#!/bin/bash
a=0
until [ $a -gt 10 ]
do
echo $a
a=`expr $a + 1`
done
#运行结果:
#输出结果为:
0
1
2
3
4
5
6
7
8
9

case … esac

case … esac 与其他语言中的 switch … case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case … esac 语句,esac(就是 case 反过来)作为结束标记。

case … esac 语法格式如下:
case 值 in
模式1)
模式1匹配成功
;;
模式2)
模式2匹配成功
;;
*)
以上都没匹配成功
;;
esac

case工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
下面的脚本提示输入1到4,与每一种模式进行匹配:
echo ‘输入 1 到 4 之间的数字:’
echo ‘你输入的数字为:’
read aNum
case $aNum in

  1. echo ‘你选择了 1’
    ;;
  2. echo ‘你选择了 2’
    ;;
  3. echo ‘你选择了 3’
    ;;
  4. echo ‘你选择了 4’
    ;;
    *) echo ‘你没有输入 1 到 4 之间的数字’
    ;;
    esac
    输入不同的内容,会有不同的结果,例如:
    输入 1 到 4 之间的数字:
    你输入的数字为:
    3
    你选择了 3
    case 后为取值,值可以为变量或常数。
    值后为关键字 in,接下来是匹配的各种模式,每一模式最后必须以右括号结束,模式支持正则表达式。
    #!/bin/sh
    site=“sixstaredu”
    case “$site” in
    “baidu”) echo “百度”
    ;;
    “sixstaredu”) echo “六星教育”
    ;;
    “taobao”) echo “淘宝网”
    ;;
    esac
    输出结果为:
    六星教育

跳出循环

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:
break和continue。

break

break命令允许跳出所有循环(终止执行后面的所有循环)。

#下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
#执行以上代码,输出结果为:
输入 1 到 5 之间的数字:3
你输入的数字为 3!
输入 1 到 5 之间的数字:7
你输入的数字不是 1 到 5 之间的! 游戏结束

continue

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
对上面的例子进行修改:

#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done
#运行代码发现,当输入大于5的数字时,该例中的循环不会结束,语句 echo "游戏结束" 永远不会被执行。

Shell传递参数

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……

#实例
#以下实例我们向脚本传递三个参数,并分别输出,其中 $0 为执行的文件名(包含文件路径):
#!/bin/bash
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
#执行脚本
[root@localhost ~]# ./hello.sh 1 2 3 #注意传递参数
#输出结果
Shell 传递参数实例!
执行的文件名:./hello.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

另外,还有几个特殊字符用来处理参数:

参数处理说明
$#传递到脚本的参数个数
$*以一个单字符串显示所有向脚本传递的参数。 如"$*“用「”」括起来的情况、以"$1 $2 …$n"的形式输出所有参数。
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@ ∗ 相 同 , 但 是 使 用 时 加 引 号 , 并 在 引 号 中 返 回 每 个 参 数 。 如 " *相同,但是使用时加引号,并在引号中返回每个参数。 如" 使"@“用「”」括起来的情况、以"$1" “ 2 " … " 2" … " 2""n” 的形式输出所有参数。
$-显示Shell使用的当前选项,与set命令功能相同。
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
#!/bin/bash
echo "Shell 传递参数实例!";
echo "第一个参数为:$1";
echo "参数个数为:$#";
echo "传递的参数作为一个字符串显示:$*";
#执行脚本
[root@localhost ~]# ./hello.sh 1 2 3 #注意传递参数
#输出结果
Shell 传递参数实例!
第一个参数为:1
参数个数为:3
传递的参数作为一个字符串显示:1 2 3S

$* 与 $@ 区别:
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)

#!/bin/bash
echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done
#执行脚本,
[root@localhost ~]# ./hello.sh 1 2 3 #注意传递参数
#输出结果如下所示:
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3

shell函数

linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
shell中函数的定义格式如下:

[ function ] funname [()]
{
	action;
	[return int;]
}

说明:
1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255

下面的例子定义了一个函数并进行调用:

#!/bin/bash
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
#输出结果:
-----函数开始执行-----
这是我的第一个 shell 函数!
-----函数执行完毕-----

用return返回数据,函数返回值在调用该函数后通过 $? 来获得。

注意: 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

下面定义一个带有return语句的函数:

#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum$anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
#输出类似下面:
这个函数会对输入的两个数字进行相加运算...
输入第一个数字:
1
输入第二个数字:
2
两个数字分别为 1 和 2 !
输入的两个数字之和为 3 !

函数参数

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
带参数的函数示例:

#!/bin/bash
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
#输出结果:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

注意:
$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
另外,还有几个特殊字符用来处理参数:

参数处理说明
$#传递到脚本或函数的参数个数
$*以一个单字符串显示所有向脚本传递的参数
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@与$*相同,但是使用时加引号,并在引号中返回每个参数。
$-显示Shell使用的当前选项,与set命令功能相同。
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

文件包含

和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。

Shell 文件包含的语法格式如下:

#. filename # 注意点号(.)和文件名中间有一空格
#或
#source filename
#创建两个shell脚本如下:
#test.sh 代码如下

#!/bin/bash
a="Hello"
hello.sh 代码如下
#!/bin/bash
#使用 . 号来引用test1.sh 文件
. ./test.sh
# 或者使用以下包含文件代码
# source ./test.sh
echo "$a world!"
#输出结果:
Hello world!
#**注:**被包含的文件 test.sh 不需要可执行权限。

Shell输入/输出重定向

大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。

重定向命令列表如下:

命令说明
command > file将输出重定向到 file。
command < file将输入重定向到 file。
command >> file将输出以追加的方式重定向到 file。
n > file将文件描述符为 n 的文件重定向到 file。
n >> file将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m将输出文件 m 和 n 合并。
n <& m将输入文件 m 和 n 合并。
<< tag将开始标记 tag 和结束标记 tag 之间的内容作为输入。

需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

输出重定向

重定向一般通过在命令间插入特定的符号来实现。特别的,这些符号的语法如下所示:
command1 > file1

上面这个命令执行command1然后将输出的内容存入file1。
注意任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用 >> 操作符。
执行下面的命令,它将命令的完整的输出重定向在用户文件中(test):

echo “hello redirect” > test

执行后,并没有在终端输出信息,这是因为输出已被从默认的标准输出设备(终端)重定向到指定的文件。
你可以使用 cat 命令查看文件内容:
cat test
执行代码:

[root@localhost test]# echo "hello redirect" > test
[root@localhost test]# cat test
hello redirect

如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾,例如:

[root@localhost test]# echo "hello redirect" >> test
[root@localhost test]# cat test
hello redirect
hello redirect

输入重定向

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值