曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 8047|回复: 0
打印 上一主题 下一主题

[系统应用] [functions.sh]config_foreach

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2014-12-5 15:35:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在 /lib/functions.sh 文件中,config_foreach() 函数用来迭代每一个 section 。下面看它的代码定义:
[Bash shell] 纯文本查看 复制代码
config_foreach() {                                                               
        local ___function="$1"                                                          
        [ "$#" -ge 1 ] && shift                                                             
        local ___type="$1"                                                              
        [ "$#" -ge 1 ] && shift                                                         
        local section cfgtype                                                  
                                                                                        
        [ -z "$CONFIG_SECTIONS" ] && return 0                                           
        for section in ${CONFIG_SECTIONS}; do 
                config_get cfgtype "$section" TYPE 
                [ -n "$___type" -a "x$cfgtype" != "x$___type" ] && continue             
                eval "$___function \"\$section\" \"\$@\""                               
        done                                                                            
}



该函数至少得带有一个参数:

1. 一个回调函数,回调函数是一个自定义的函数,必须在调用 config_foreach 之前就定义。回调函数会在每次遇到 section 时被调用执行,这个从上面代码的 eval "$___function \"\$section\" \"\$@\""  (位于 for 中)可以看到。


2. 类型(可选),指定了类型,那么 config_foreach 就只关心该类型的 section (比如 network 中的 interface),而忽略其它的。


3. 附加参数(可选),如果给了这些参数,那么都会一股脑的传递到回调函数之中。


下面给出一段测试代码,考察该函数的具体应用:
[Bash shell] 纯文本查看 复制代码
#!/bin/sh 

. /lib/functions.sh

config_load network


handle_interface() {
		
	local iface="$1"

	echo $iface
}

config_foreach handle_interface interface



运行输出:
# ./tmp
loopback
lan
wan
wan6

由此可见,它遍历了类型为 interface 的所有 section ,并输出了 section 名。

以操作 /etc/config/network 为例,现在回过头来看一下 config_foreach 的具体代码:

开头部分,分别将回调函数传和类型递给本地变量 ___function 和 ___type。


接着,判断 $CONFIG_SECTIONS 是否为空,为空则返回 0 ([ -z "$CONFIG_SECTIONS" ] && return 0 )。其中,$CONFIG_SECTIONS 的值已经在 config() 和 append() 等函数里获得。


再接着,通过一个循环 for section in ${CONFIG_SECTIONS}; 遍历所有 SECTIONS,比如有 lookback, lan, wan, wan6 等。


接着,使用 config_get 函数 config_get cfgtype "$section" TYPE 获取 section 的类型(比如 interface, globals, switch, switch_vlan 等),并将其赋值给 cfgtype 变量中。这里第 3 个参数 TYPE 是为了使用 config() 函数中导出的相应变量,比如 CONFIG_lookback_TYPE 。在 config() 函数的最后一句里正是对这个变量进行了赋值:
  1. export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_TYPE=$cfgtype"
复制代码

注意,上面的 $cfgtype 只是 config() 函数里的局部变量,并不是 config_get 里的 cfgtype 。比如在 network 里有这么个定义:config interface lookback ,那么 config() 里的 $cftype 就是 interface 。

在获得 section 的类型名后,再用语句 [ -n "$___type" -a "x$cfgtype" != "x$___type" ] && continue 判断所获得类型是否和 config_foreach() 函数中的类型一致,若是不一致,则重新跳回 for 循环,进行下一个迭代。若是一致,那么调用 config_foreach() 中最后一条语句:
  1. eval "$___function \"\$section\" \"\$@\""
复制代码

这条语句就是调用自定义的回调函数。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 13:37 , Processed in 0.060839 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表