简介
shell脚本执行方式Shell 是一个用 C 语言编写的程序,通过 Shell 用户可以访问操作系统内核服务。它类似于 DOS 下的 command 和后来的 cmd.exe。Shell 既是一种命令语言,又是一种程序设计语言。
Shell script 是一种为 shell 编写的脚本程序。Shell 编程一般指 shell脚本编程,不是指开发 shell 自身。
Shell 编程跟 java、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,一个系统可以存在多个 shell,可以通过 cat /etc/shells 命令查看系统中安装的 shell。
Bash 由于易用和免费,在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。
快速入门
新建 /export/data/shell/hello.sh 文件
#!/bin/bash
echo 'hello world'
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。注意,在shell脚本中除了第一行的#表示特殊格式外,其他地方的
#一般表示注释。
echo命令用于向窗口输出文本。
解释器
Java需要虚拟机解释器, 同理 shell脚本也需要解析器,查看Linux系统支持的解释器:
[root@node1 shell]#cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
常见Shell解释器:
sh: 的全称是 Bourne shell,由 AT&T 公司的 Steve Bourne开发,为了纪念他,就用他的名字命名了。sh 是UNIX 上的标准 shell,很多 UNIX 版本都配有 sh。sh 是第一个流行的 Shell。
Bash:从名称可以看出是Bsh的升级版本,是著名的开源软件项目,目前大多数的Linux版本都使用Bash 作为默认的Shell程序,当运行Shell程序时,实际运行的是Bash程序
Csh:是因使用C语言的语法风格而得名,在用户的命令行交互界面上进行了很多改进,并增加了历史,别名,文件名替换,作业掏等功能,相比Bsh,Csh在更加适用为 用户提供命令交互操作
在现代的 Linux上,sh 已经被 bash 代替,/bin/sh往往是指向/bin/bash的符号链接。
如果你希望查看当前 Linux 的默认 Shell,那么可以输出 SHELL 环境变量:
[root@node1 shell]# echo $SHELL
/bin/bash
输出结果表明默认的 Shell 是 bash。
shell脚本执行方式
shell脚本有三种执行方式:
- 方式一:sh执行
sh执行,进入脚本的工作目录,然后使用对应的sh或bash来执行脚本,这种执行方式,脚本文件不需要具有可执行权限。
[root@node1 ~]# cd /export/data/shell/
[root@node1 shell]#sh hello.sh
hello world
- 方式二:工作目录执行
执行脚本时,先进入到脚本所在的目录,然后使用 ./脚本方式执行,这种执行方式,必须保证脚本文件具有可执行权限。
[root@node1 ~]#cd /export/data/shell/
[root@node1 shell]# chmod +x hello.sh
[root@node1 shell]# ./hello.sh
hello world
- 方式三:绝对路径执行
绝对路径中执行,指的是直接从根目录/到脚本目录的绝对路径,这种执行方式,必须保证脚本文件具有可执行权限。
[root@node1 ~]# /export/data/shell/hello.sh
hello world
shell的数据类型
字符串:
字符串是shell编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号。建议使用双引号,因为双引号里可以有变量和特殊字符,可以按照变量和特殊字符去使用。
声明字符串类型的变量:
整数型:
在Shell中所有的变量默认都是字符串型。默认情况下,所有的数值都是不能进行运算的,如果想要进行数学运算,可以使用“
(
(
运
算
式
)
)
”
或
“
((运算式))”或“
((运算式))”或“[运算式]”方式运算(后续讲)。
变量
简介
shell变量是一种很“弱”的变量,默认情况下,一个变量保存一个串,shell不关心这个串是什么含义。所以若要进行数学运算,必须使用一些命令例如let、declare、expr、双括号等。
在shell中有3种变量:用户变量、环境变量、特殊变量,其中用户变量在编程过程中使用量最多,环境变量主要是在程序运行时需要设置,特殊变量在对参数判断和命令返回值判断时会使用,。
变量的定义语法:
变量名=变量值
变量的定义需遵循的规则
- 变量名可以由字母、数字和下画线组成,但是不能以数字开头。
- 在 Bash中,变量的默认类型都是字符串型,如果要进行数值运算,则必须使用特殊命令。
- 变量用等号"=“连接值,”="左右两侧不能有空格。
- 变量值中如果有空格,则需要使用单引号或双引号包含,如 test=“hello world!”。双引号括起 来的内容"$"和反引号者都拥有特殊含义,而单引号括起来的内容都是普通字符。
- 在变量值中,可以使用转义符""。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
用户变量
定义变量
在对变量赋于字符串值时,建议使用引号将其包裹。如果字符串中存在空格,请一定要使用单引号或双引号将整个内容包裹。注意:单引号里的内容原封不动的输出,双引号里有变量的调用则会调用变量
[root@node1 shell]# username="wp"
访问变量
要对变量进行调用时,在变量名前加美元符号$
[root@node1 shell]# echo $username
如果需要增加变量的值,那么可以进行变量值的叠加。不够变量需要用双引号包含"$变量名"或${变量名}
[root@node1 ~]# username="wp"
[root@node1 ~]# echo $usernamedb.log #这种方式不可以
.log
[root@node1 ~]# echo "$username"db.log #可以
wp.log
[root@node1 ~]# echo ${username}db.log #可以
wp.log
测试脚本test1.sh
#! /bin/bash
string="I am shell"
num=5
echo "a=${num},string=${string}"
执行脚本
[root@node1 shell]# sh test1.sh
a=5,string=I am shell
变量的其他赋值方式
- 可以使用read关键字从键盘获取内容赋值给变量
- 可以通过
(
l
i
n
u
x
命
令
)
或
者
(linux命令)或者
(linux命令)或者
linux命令
来执行linux命令,并将命令的执行结果赋值给变量
脚本内容:test2.sh
#! /bin/bash
echo "who are you?"
read name #从键盘获取变量的值
pwd_string=$(pwd) #将当前的绝对路径赋值给pwd_string变量
date_string=`date` #将当前时间赋值给date_string变量
echo "hello, $name"
echo $pwd_string
echo $date_string
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
下面的例子尝试更改只读变量,结果报错
test3.sh
#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl
myUrl="http://www.runoob.com"
运行脚本,结果如下:
/bin/sh: NAME: This variable is read only.
删除变量
使用 unset 命令可以删除变量。语法:
unset variable_name
变量被删除后不能再次使用。unset 命令不能删除只读变量。
实例:
test4.sh
#!/bin/sh
myUrl="http://www.runoob.com"
unset myUrl
echo $myUrl
以上实例执行将没有任何输出。
环境变量
当shell程序启动时,都自动设置一组变量,这组变量就是环境变量。shell中的所有命令都可以使用这些变量,环境变量可以在/etc/profile中设置,环境变量的名字习惯上使用大写字母。
- 常见的环境变量
可以使用env命令查看所有的系统环境变量
[root@node1 shell]# env
XDG_SESSION_ID=2
HOSTNAME=node1
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.88.5 8047 22
CONDA_SHLVL=0
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root
- 常见的环境变量:
PATH 决定了shell将到哪些目录中寻找命令或程序
HOME 当前用户主目录
HISTSIZE 历史记录数
LOGNAME 当前用户的登录名
HOSTNAME 指主机的名称
SHELL 当前用户Shell类型
LANGUGE 语言相关的环境变量,多语言可以修改此环境变量
MAIL 当前用户的邮件存放目录
PS1 基本提示符,对于root用户是#,对于普通用户是$
- 自定义环境变量
- vi /etc/profile ,在文件末尾加上要定义的环境变量,语法如下:
export 变量名=变量值
export SERVICE_HOST=www.it.cn
- wq 退出
- source /etc/profile
- 输入 env 查看环境变量,是否有自己定义的环境变量。
- 使用环境变量
环境变量的使用方式和普通变量是一样的:$环境变量名
[root@node1 shell]# echo $SERVICE_HOST
www.it.cn
我们可以在执行 Shell 脚本时,向脚本传递参数,这时候可以使用特殊变量来获取参数,Shell常用的特殊变量如下:
变量 | 解释 |
---|---|
$# | 命令行参数的个数 |
$n | $1表示第一个参数,$2表示第二个参数,以此类推 |
$0 | 当前程序的名称 |
$? | 前一个命令或许或函数的返回码 |
$* | 以“参数1 参数2 。。。”形式保存所有参数 |
$@ | 以“参数1”“参数2”。。。形式保存所有参数 |
$$ | 本程序的(进程ID号)PID |
$! | 上一个命令的PID |
实例:
以下实例我们向脚本传递三个参数,并分别输出,其中 $0 为执行的文件名:
test5.sh
#!/bin/bash
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
echo "参数个数为:$#";
echo "传递的参数作为一个字符串显示*:$*";
执行脚本:
[root@node1 shell]# chmod +x test5.sh
[root@node1 shell]# ./test5.sh aaa bbb ccc
Shell 传递参数实例!
执行的文件名:./test5.sh
第一个参数为:aaa
第二个参数为:bbb
第三个参数为:ccc
参数个数为:3
传递的参数作为一个字符串显示*:aaa bbb ccc
$* 与 $@ 区别:
- 相同点:都是引用所有参数。
- 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,则 " * " 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)。
字符串
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号
name='乔布斯'
str='我很崇拜$name'
echo $str
输出结果为:
我很崇拜$name
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的,单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号
name="乔布斯"
str="我很崇拜$name"
echo $str
输出结果为:
我很崇拜 乔布斯
双引号的优点
- 双引号里可以有变量
- 双引号里可以出现转义字符
拼接字符串
使用双引号拼接
test6.sh
#!/bin/bash
yourname="吴恩达"
wenhou_1="你好,$yourname ."
wenhou_2="你好,"$yourname" ."
wenhou_3="你好,\"$yourname\" ."
echo $wenhou_1 $wenhou_2 $wenhou_3
输出结果为:
你好,吴恩达 . 你好,吴恩达 . 你好,"吴恩达" .
使用单引号拼接
test7.sh
#!/bin/bash
yourname="乔布斯"
wenhou_4='你好,$yourname.'
wenhou_5='你好,'$yourname.''
wenhou_6='你好,"$yourname" .'
echo $wenhou_3 $wenhou_4 $wenhou_5
输出结果:
你好,$yourname. 你好,乔布斯. 你好,"$yourname" .
获取字符串的长度
test8.sh
#!/bin/bash
string="jobs"
echo ${string} # 输出结果: jobs
echo ${#string} # 输出结果: 4
提取字符串
以下实例从字符串第 2 个字符开始截取 2 个中文字符:
test9.sh
#!/bin/bash
string="敢于亮剑决不后退"
echo ${string:2:2} # 输出结果为: 亮剑
查找子字符串
#!/bin/bash
string="i am a boy"
echo `expr index "$string" am` # 输出是: 3
注意: 以上脚本中 ` 是反引号(Esc下面的),而不是单引号 ',不要看错了哦。
算数运算符简介
Shell 和其他编程一样,支持包括:算术、关系、布尔、字符串等运算符。原生 bash 不支持简单的数学运算,但是可以通过其他命令来实现,例如expr。expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
例如,两个数相加:
val=`expr 2 + 2`
echo $val
注意:
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。
完整的表达式要被包含,注意不是单引号,在 Esc 键下边。
下表列出了常用的算术运算符,假定变量 a为10,变量b为20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ a == b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ a != b ] 返回 true。 |
例子
test11.sh
#!/bin/bash
a=4
b=20
#加法运算
echo expr $a + $b
#减法运算
echo expr $a - $b
#乘法运算,注意*号前面需要反斜杠
echo expr $a \* $b
#除法运算 echo $a / $b
#此外,还可以通过$(())、$[]进行算术运算。
echo "a = $a"
c=$((a+b))
d=$[a+b]
echo "c = $c"
echo "d = $d"
流程控制
Shell提供了丰富的语句判断方式,包括数字,字符串和文件。
语句判断
数字
运算符 | 说明 |
---|---|
-eq | 检测两个数是否相等,相等返回 true。 |
-ne | 检测两个数是否不相等,不相等返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 |
字符串
判断符 | 说明 |
---|---|
-n STRING | 字符串长度不为零 |
-z STRING | 字符串长度为0 |
= | 判断两个字符串是否一样 |
!= | 判断两个字符串是否不一样 |
文件
判断符 | 说明 |
---|---|
-f | 存在且是普通文件 |
-d | 存在且是目录 |
-h | 存在且是符号链接 |
-e | 文件存在 |
–r | 文件存在并且可读 |
–w | 文件存在并且可写 |
–x | 文件存在并且可执行 |
if语句
if 语句语法格式
if condition
then
command1
command2
...
commandN
fi
例子:
1.判断当前系统是否有多个ssh进程,如果有则打印true
test12.sh
#!/bin/bash
if [ $(ps -ef | grep -c "ssh") -gt 1 ]
then
echo "true"
fi
2.判断/media/cdrom目录是否存在,若不存在就去创建这个目录
test13.sh
#!/bin/bash
DIR="/media/cdrom"
if [ ! -d $DIR ]
then
mkdir -p $DIR
fi
if else
if else 语法格式:
if condition
then
command1
command2
...
commandN
else
command
fi
实例:
- 根据年龄判断是否成年
test14.sh
#!/bin/bash
read -p "Enter your age(1-100):" age
if [ $age -ge 18 ]
then
echo '已经成年!'
else
echo '未成年!'
fi
- if else语句经常与test命令结合使用
test 命令允许你做各种测试并在测试成功或失败时返回它的退出状态码(为0表示为真,为1表示为假)。使用这个状态码,可以让 Bash 对测试的结果做出反应。
test 命令的语法为:
test EXPRESSION
或
[ EXPRESSION ]
test15.sh
#!/bin/bash
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
echo '两个数字相等!'
else
echo '两个数字不相等!'
fi
if else-if else
if else-if else 语法格式
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
实例:
- 以下实例判断两个变量是否相等:
test16.sh
#!/bin/bash
echo "请输入a的值:"
read a
echo "请输入b的值:"
read b
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
- 输入成绩,判断成绩“优”“良”“中”
test17.sh
#!/bin/bash
read -p "Enter your score(0-100):" n #-p参数表示给出提示信息
if [ $n -ge 85 ] && [ $n -le 100 ] ; then
echo "优"
elif [ $n -ge 70 ] && [ $n -le 84 ] ; then
echo "良"
elif [ $n -ge 60 ] && [ $n -le 69 ] ; then
echo "中"
else
echo "差"
fi
for循环
与其他编程语言类似,Shell支持for循环。
格式1-字符型循环
for循环一般格式为:
for 变量 in 值1 值2 值3…
do
程序
done
当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。
in列表是可选的,如果不用它,for循环使用命令行的位置参数。
实例:
- 顺序输出当前列表中的数字:
test18.sh
#!/bin/bash
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
- 顺序输出字符串中的字符
test19.sh
#!/bin/bash
for str in 'This is a string'
do
echo $str
done
输出结果:
This is a string
- 打印/root目录下所有文件的名字
test20.sh
#!/bin/bash
for file in $(ls /root)
do
echo $file
done
- 求1-100的和
test21.sh
#!/bin/bash
s=0
#从1加到100
for(( i=1;i<=100;i=i+1))
#定义循环100次
do
#每次循环给变量s赋值
s=$(($s+$i))
done
#输出从1加到100的和
echo "The sum of 1+2+..+100 is : $s"
2.9.3.2. 格式2-数字性循环
该格式的语法如下:
for ((初始值;循环控制条件;变量变化))
do
程序
done
需要注意以下几点:
初始值:在循环开始时,需要给某个变量赋予初始值,如 i=1。
循环控制条件:用于指定变量循环的次数,如 i<=100,则只要 i 的值小于等于 100,循环就会继续。
变量变化:每次循环之后,变量该如何变化,如 i=i+1,代表每次循环之后,变量的值都加 1。
语法二和其他语言中的 for 循环类似,也就是事先决定循环次数的固定循环。
test22.sh
#!/bin/bash
for ((i = 0; i <= 5; i++))
do
echo "welcome $i times"
done
while循环
while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
while 条件
do
程序
done
- 案例
以下是一个基本的while循环,测试条件是:如果int小于等于5,那么条件返回真。int从0开始,每次循环处理时,int加1。运行上述脚本,返回数字1到5,然后终止。
test23.sh
#!/bin/bash
num=1
while(( $num<=5 ))
do
echo $num
let "num++"
done
运行脚本,输出:
1
2
3
4
5
无限循环
无限循环语法格式:
while :
do
command
done
或者
while true
do
command
done
或者
for (( ; ; ))
case语句
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
case工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
下面的脚本提示输入1到4,与每一种模式进行匹配:
test25.sh
#!/bin/bash
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
输入不同的内容,会有不同的结果
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。
break
break命令允许跳出所有循环(终止执行后面的所有循环)。
下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。
test26.sh
#!/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命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
对上面的例子进行修改:
test27.sh
#!/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 "游戏结束" 永远不会被执行。
函数
语法
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
shell中函数的定义格式如下:
[ function ] funname()
{
action;
[return int;]
}
说明:
- 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
- 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
实例:
- 定义一个函数并进行调用
test28.sh
#!/bin/bash
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
输出结果:
-----函数开始执行-----
这是我的第一个 shell 函数!
-----函数执行完毕-----
- 定义一个带有return语句的函数
test29.sh
#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
输出类似下面:
这个函数会对输入的两个数字进行相加运算...
输入第一个数字:
1
输入第二个数字:
2
两个数字分别为 1 和 2 !
输入的两个数字之和为 3 !
需要注意: 虽然此处根据 $? 返回了函数的函数值, 但本质其实不是, $? 是用于返回上一个命令的执行完的一个状态, 而这个状态值为(0~255)的范围, 当执行成功, 状态码为0 , 返回其他任意值都表示有异常, 故正确的函数的返回值, 应该如下的操作:
#!/bin/bash
echo "---------第一种方式: ---------------"
result=""
sum() {
#1 让用户输入两个数字
read -p "请输入第一个数字: " num1
read -p "请输入第二个数字:" num2
result=$[$num1+$num2]
}
sum
echo "返回值为: ${result}"
echo "---------第二种方式------------"
sum1() {
#1 让用户输入两个数字
read -p "请输入第一个数字: " num1
read -p "请输入第二个数字:" num2
result=$[$num1+$num2]
echo "${result}"
}
result1=$(sum1)
echo "返回值: ${result1}"
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 的形式来获取参数的值,例如,1表示第一个参数,$2表示第二个参数…
带参数的函数示例:
test30.sh
#!/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 !
注意,(centos6.x版本)不能获取第十个参数,获取第十个参数需要{10}。当n>=10时,需要使用${n}来获取参数。
数组
定义数组
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。
与大部分编程语言类似,数组元素的下标由0开始。
Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:
array_name=(value1 … value)
实例:
test31.sh
#!/bin/bash
my_array=(A B "C" D)
#我们也可以使用下标来定义数组:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
读取数组
读取数组元素值的一般格式是:
${array_name[index]}
实例
test32.sh
#!/bin/bash
my_array=("A" "B" "C" "D")
echo "第一个元素为: ${my_array[0]}"
echo "第二个元素为: ${my_array[1]}"
echo "第三个元素为: ${my_array[2]}"
echo "第四个元素为: ${my_array[3]}"
执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh
第一个元素为: A
第二个元素为: B
第三个元素为: C
第四个元素为: D
获取数组中的所有元素
使用@ 或 * 可以获取数组中的所有元素,例如:
test33.sh
#!/bin/bash
my_array[0]=“A”
my_array[1]=“B”
my_array[2]=“C”
my_array[3]=“D”
echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}"
执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh
数组的元素为: A B C D
数组的元素为: A B C D
获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
test34.sh
#!/bin/bash
my_array[0]=A
my_array[1]=B
my_array[2]=C
my_array[3]=D
echo "数组元素个数为: ${#my_array[*]}"
echo "数组元素个数为: ${#my_array[@]}"
执行脚本,输出结果如下所示:
$ chmod +x test.sh
$ ./test.sh
数组元素个数为: 4
数组元素个数为: 4
遍历数组
test35.sh
#!/bin/bash
my_arr=(AA BB CC)
for var in ${my_arr[*]}
do
echo $var
done
shell脚本综合案例猜字游戏
规则
游戏规则为:程序内置一个1到100 之间的数字作为猜测的结果,由用户猜测此数字。用户每猜测一次,由系统提示猜测结果:大了、小了或者猜对了;直到用户猜对结果,则提示游戏结束。
代码
guess_number.sh
#!/bin/bash
#生成100以内的随机数 提示用户猜测 猜对为止
#random 系统自带,值为0-32767任意数
#随机数1-100
num=$[RANDOM%100+1]
#read 提示用户猜数字
#if判断
while :
do
read -p "计算机生成了一个 1‐100 的随机数,你猜: " cai
if [ $cai -eq $num ]
then
echo "恭喜,猜对了"
exit
elif [ $cai -gt $num ]
then
echo "不巧,猜大了"
else
echo "不巧,猜小了"
fi
done