linux基础(二十)—-linux编程基础—-子程序—-函数
最后更新于:2022-04-01 11:25:01
写一个又大又复杂的程序的技巧之一,就是将该程序分解成一些称之为子程序的小程序,而在每一个子程序中,又可以把重复出现的代码组织到一起形成一个函数。
函数和子程序执行的是主程序某一特定的任务。我们要做的工作就是写一个主程序,当需要某一个函数和子程序的时候就调用它们。
本章先了解函数。
在编写Linux程序的时候,有时不得不一遍又一遍地重写某些相同的命令。例如,给朋友写一份邀请信,请他们来参加一个狂欢舞会。可把这些信息写在一个for in循环中,并将每个朋友的名字放在一个单词表中。当然,也可以把每一份邀请信都写进程序中,只不过是将内容重写几次罢了。或者使用一个函数。
函数(function)是Linux程序的一部分,与程序的其余部分是分开的。试设想一下:一个函数就像程序中的一个分隔仓。我们先给一个函数取一个惟一的名字(即函数名),然后就可以把经常要使用的一条或多条命令放入函数之中。
当linux需要使用存放在函数中的命令时,可以在程序中键人该函数的名字。因此,通过使用函数名就可以重复使用函数中的命令,而不必再重写这些命令。譬如,把那些邀请词放在一个函数中。
在每次调用函数时,可以给函数传递一定的信息。这个过程称之为给函数传递参数。因此,可以创建一个打印邀请信的函数,每调用它一次,就给函数传递一个名字,而函数则会自动地把名字赋给函数中的某个变量。以后,当涉及到那位朋友的时候,代表他的就是一个变量,而不是他的名字。
通常使用函数来处理传递给函数的某些信息,然后,将处理结果返回到程序的调用处。函数处理后返回的结果称之为返回值(return value)。我们可以在程序中利用这个返回值。
如果需要重写某段代码,就可以使用函数来代替它。
## 创建一个函数
在使用一个函数之前,必须先在程序中定义一个函数。因此,创建一个函数最好的地方是在程序的开始位置。创建函数也称之为定义函数,定义的结果称为函数定义。
定义一个函数请遵循下述步骤:
1.首先在程序中键入一个关键字function。
它表示要创建一个函数。
2.给函数起一个名字。且它在程序中没有任何重名。
函数的名称最好能反映函数的功能。
3.在函数名和第一个命令之间要使用一个开大括号"{"。
它表示函数执行命令的入口。
4.在函数体中键入所需要的任何命令。
在函数体中使用在本书中讨论的任何命令都可以。
5.在函数体每一个命令之后,下一个命令之前用一个分号";"隔开。
注意,分号和命令之间不要留有空格。分号";"表示一个特定的命令结束。
6.在最后一个命令的分号";"之后用一个闭大括号"}"。
注意,在最后一个分号"}"和"|"之间不要留有空格。闭大括号"|"表示函数定义的结束。
下面是函数定义的一般格式:
~~~
function name
{
command;
command;
}
~~~
下面是一个典型的函数定义,它的作用是在屏幕上显示一条欢迎信息(此函数例子在本
章后面还会引用到,请留心)。
~~~
function display
{
echo "Welcome to the world"
echo "of functios"
}
~~~
## 调用一个函数
在定义了一个函数以后,调用它是非常容易的。我们需要做的就是在需要使用该函数的地方用一下函数名即可。
通过函数调用,Linux会自动寻找该函数的定义,并执行其中的每一条指令。
在程序执行到闭大括号“}”后,Linux返回到调用函数的下一行,并继续执行其他的指令。
下面是函数调用的一个典型例子:
~~~
#!/bin/bash
clear
function display
echo "Welcome to the world"
echo "of functions. "
}
display
~~~
## 给函数传递参数
例如,假设要写一个验证用户ID和密码( password)的函数,这个函数除了ID和密码之外,还包括所有验证用户身份所必需的命令和信息。在每次调用函数时,除了ID和密码可以不同之外,其余各部分都应相同。
如果读者想在程序中调用该函数,就把ID和密码作为参数传递给函数,linux把它们赋给某些变量。在这个程序中,这两个变量分别是$$1和$$2。每一个数字都指向它所对应的传递来的参数。注意,由于Linux在这里期望的是数字,所以不能用其他的字符如varl来取代这些变量中的数字的。
因此,可以用变量来取代函数定义中的信息。例如,ID是传递给函数的第一个参数,密码是传递给函数的第二个参数。因此,在函数定义中,当需要引用ID时就可以用变量$1,需要引用密码时可以用变量$2。
请看下面的例子:
~~~
#!/bin/bash
clear
function verify
{
if [$1 -eq "Bob" ]&&[$2 -eq "555"]
then
echo "Verified"
eise
echo "Rejected"
fi
}
verify Bob 555
~~~
## 验证传递给函数的参数的个数
如果程序不能给一个函数传递它所需要的全部信息,可能会遇到麻烦。例如,一个函数可能要依据程序提供的某些信息来进行某种计算操作。不过,如果程序根本不给函数传递什么 信息,也可能会出现错误。
变量$#包含了传递给函数的参数的个数。通过对变量$#的值和函数实际需要的参数的
个数进行比较,就可以决定是否阻止函数处理传递来的信息。请看下面的示例:
~~~
#!/bin/bash
clear
function verify
{
if [$# -ne 2]
then
echo "Wrong number of arguments!"
else
if[$1 -eq "Bob"] &&[$2 -eq "555"]
then
echo "Verified"
else
echo "Rejected"
fi
fi
}
verify Bob 555
~~~
## 与子程序共享函数
子程序同样也可以使用程序员建立的函数。只要把子程序设想成是程序中的一个程序即可。
我们建立一个用函数验证用户ID和密码的程序。但这次却想在另一个不含有该函数的程序中使用该函数。当然,不是把该函数复制到第二个程序中,而是让第二个程序(子程序)也能分享第一个程序中的函数。
我们可以用export命令输出函数,实现子程序之间共享函数。然后,就可以在子程序中调用该子函数。请看下面的例子:
~~~
#!/bin/bash
clear
function verify
{
if [$# -ne 2]
then
echo "Wrong number of arguments!"
else
if[$1 -eq "Bob"]&&[$2 -eq "555"]
then
echo "Verified"
else
echo "Rejected"
fi
fi
}
export verify
subprogram1
~~~
现在对加在函数定义之后的两行说明如下:
1.在函数定义结束符“}”之后,用export命令来说明子程序subprogram1可以访问函数verify。
2.程序中最后一行是调用子程序subprogram1。注意,子程序subprogram1并没有包含函数verify的定义,但子程序可以调用它,因为在调用予程序之前已用export命令说明了输出该函数verify。
子程序subprogram1如下:
~~~
#!/bin/bash
clear
verify "Bob" "555"
~~~
## 从函数返回信息
函数就像一条双行道,程序可以发送信息给函数,函数可以回送信息给程序。比如说,不是用函数verify验证一个用户的ID和密码是否正确,而是让函数将它处理后的结果返回给调用程序。
那么,调用程序就要决定它下面该如何操作。
函数的返回值通常存储在变量$?中。但要注意,返回值必须是在0到256之间的一个整数。因此,是不能将字符串作为返回值返回的。
通常是用一个关键字return,再在其后加上一个要返回的值的方式,从函数返回一个值。
由于返回值是一个整数,因此必须给每一个要返回的整数赋予一定的含义。例如,常用0表示函数运行正常,用非0表示函数运行出错。
关键字return可以放在函数中的任意位置,但它通常放在函数验证某些值-----如比较ID和密码的位置之后。Linux执行到return之后,函数就停止往下执行,返回到主程序的调用行。
若想知道如何从函数返回一个值,请看下面的例子:
~~~
#!/bin/bash
clear
function verify
{
if [$# -ne 2]
then
return 1
else
if [$1 -eq "Bob"]&&[$2 -eq "555"]
then
return 0
else
return 2
echo "Rejected"
fi
fi
}
verify Bob 555
case $? in
do
0)
echo "Verified"
;;
1)
echo "Wrong number of arguments!"
;;
2)
echo "Rejected"
;;
done
~~~