function
所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。可以将函数看作是脚本中的一段代码,但是有一个主要区别。执行函数时,它保留当前shelll和内存信息。如果执行或调用一个脚本文件中的另一段代码,将创建一个单独的shell,因而去除所有原脚本中定义的存在变量。
函数可以放在同一个文件中作为一段代码,也可以放在只包含函数的单独文件中。
格式两种
function(这个关键字可以不要) func_name(){
#函数体内容
}
函数调用:func_name parm
函数体中,可以通过$1 $2 ...$9接受函数调用中的变量
函数可以通过return 返回函数执行的结果
[ function ] funname [()]
{
action;
[return int;]
}
可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
函数样例
[root@250-shiyan sh]# bash uu
Please input the times of print you want: 7
0
1
2
3
4
5
6
[root@250-shiyan sh]# cat uu
function LoopPrint()
{
count=0;
while [ $count -lt $1 ];
do
echo $count;
let ++count;
sleep 1;
done
return 0;
}
read -p "Please input the times of print you want: " n; ####输入一个数字,用n表示
LoopPrint $n; ####取n的值作为$1,以便函数内部能取到这个参数。传递参数时,(这个例子中)一定要写成LoopPrint $n;而不能写成LoopPrint n
例如你输入的是20,则n的值($n)为20,前者表示的是把n的值,即20传递给函数LoopPrint,而后者则表示把字符n传递给函数LoopPrint。
样例解释
echo $(uname); #linux 1、定义函数可以与系统命令相同,说明shell搜索命令时候,首先会在当前的shell文件定义好的地方查找,找到直接执行。函数本质也是一个命令
declare num=1000;
uname()
{
echo "test!";
((num++));
return 100;
}
testvar()
{
local num=10;
((num++));
echo $num;
}
uname; #test! 2、执行函数,只返回echo
echo $? #100 3、需要获得函数值:通过$?获得
echo $num; #1001 4、如果需要传出其它类型函数值,可以在函数调用之前,定义变量(这个就是全局变量)。在函数内部就可以直接修改,然后在执行函数就可以读出修改过的值。
testvar; #10 5、如果需要定义自己变量,可以在函数中定义:local 变量=值 ,这时变量就是内部变量,它的修改,不会影响函数外部相同变量的值 。
echo $num; #1001
[root@250-shiyan sh]# bash ui
Linux
test!
100
1001
11
1001
1、在/home/script/目录下新建函数文件fun-1
2、在fun-1文件中编写函数findit内容
#!/bin/bash
findit ()
{
if [ $# -lt 1 ]; then #判断函数参数个数
echo "usage: findit filename";
return 1;
fi;
for loop in "$@"; #遍历调用函数的参数
do
find /home/script/ -name $loop -print;
done;
return 0
}
3、Shell中载入函数文件
.或source /home/script/fun-1
4、检查载入文件
set
set命令将在shell中显示所有的载入函数
5、调用函数
findit mysql php #在home目录查找文件mysql和文件php
当你收集一些经常使用的函数时,可以将之放入函数文件中并将文件载入shell。
文件头应包含语句#!/bin/sh,文件名可任意选取,但最好与相关任务有某种实际联系。
一旦文件载入shell,就可以在命令行或脚本中调用函数。可以使用set命令查看所有定义的函数。输出列表包括已经载入shell的所有函数。
如果要改动函数,首先用unset命令从shell中删除函数,尽管unset删除了函数以便于此函数对于shell或脚本不可利用,但并不是真正的删除。
改动完毕后,再重新载入此文件。有些shell会识别改动,不必使用unset命令,但为了安全起见,改动函数时最好使用unset命令。
调用
同一个脚本中调用函数,只需要在调用前定义即可。
从函数文件中调用函数,这种方法不会创建另一个shell,所有函数均在当前shell下执行。
调用脚本在调用前需要载入函数文件。
/etc/init.d/functions
__sed_discard_ignored_files=`*`
init_crypto () {}
find_crypto_mount_point () {}
key_is_random () {}
apply_sysctl () {}
is_false () {}
is_true () {}
is_ignored_file () {}
get_numeric_dev () {}
confirm () {}
strstr () {}
action () {}
warning () {}
passed () {}
failure () {}
sucess () {}
update_boot_stage () {}
echo_warning () {}
echo_passed () {}
echo_failure () {}
echo_sucess () {}
status () {}
pidofproc () {}
pidfileofproc () {}
killproc () {}
daemon () {}
__pids_pidof () {}
__pids_var_run () {}
__umount_loopback_loop () {}
__umount_loop () {}
__fgrep () {}
__readlink () {}
checkpid () {}
fstab_decode_str () {}
/etc/sysconfig/network-scripts/network-functions
get_hwaddr () {}
get_config_by_device () {}
get_config_by_hwaddr () {}
get_config_by_subchannel () {}
get_config_by_name () {}
get_device_by_hwaddr () {}
get_uuid_by_config () {}
need_config () {}
source_config () {}
ethtool_set () {}
expand_config () {}
toggle_value () {}
do_netreport () {}
is_nm_running () {}
is_nm_active () {}
is_nm_device_unmanaged () {}
is_available () {}
need_hostname () {}
set_hostname () {}
check_device_down () {}
check_ethtool () {}
check_link_down () {}
check_default_route () {}
find_gateway_dev () {}
add_default_route () {}
is_wireless_device () {}
install_bonding_driver () {}
is_bonding_device () {}
change_resolv_conf () {}
net_log () {}
/etc/sysconfig/ 每一种服务的变量定义
/etc/init.d 每一种服务的脚本
/etc/init.d/funtions 函数文件拥有所有的公用函数
有两套,一套是符号链接,一套是真实文件
符号链接
/etc/rc.local
/etc/rc.sysinit
/etc/rc
/etc/rc0.d
/etc/rc1.d
/etc/rc2.d
/etc/rc3.d
/etc/rc4.d
/etc/rc5.d
/etc/rc6.d
/etc/init.d
真实文件
/etc/rc.d/rc.local
/etc/rc.d/rc.sysinit
/etc/rc.d/rc
/etc/rc.d/rc0.d
/etc/rc.d/rc1.d
/etc/rc.d/rc2.d
/etc/rc.d/rc3.d
/etc/rc.d/rc4.d
/etc/rc.d/rc5.d
/etc/rc.d/rc6.d
/etc/rc.d/init.d