Openwrt系統中shell腳本獲取配置文件信息解讀

在網上查了發現關於這一方面的都沒有詳細的說明,搞得人一頭霧水,如果不清楚裏面是如何實現的,那麼這些openwrtshell腳本根本就看不下去了。沒有詳細的資料,唯有自己研究了。

Shell腳本中獲取文件信息主要依靠於以下幾個shell函數:config_load,config_get,config_set.

以解讀配置文件/etc/config/wireless爲例

/etc/config/wireless內容:

config wifi-device 'wifi0'

        option type 'qcawifi'

        option channel 'auto'

        option txpower 'auto'

        option bcnburst '1'

        option hwmode '11ng'

        option disabled '0'

        option country 'US'

.........

執行以下命令:/sbin/wifi reload

 

/sbin/wifi:

......

DEVICES=

DRIVERS=

include /lib/wifi

scan_wifi

 

case "$1" in

down) wifi_updown "disable" "$2";;

detect) wifi_detect "$2";;

status) ubus_wifi_cmd "status" "$2";;

reload) wifi_reload "$2";;

reload_legacy) wifi_reload_legacy "$2";;

flush) flush_wifi "$2" "$3" "$4";;

update) update_wifi "$2" "$3" "$4";;

radio_update) radio_update_wifi $@;;

global) global_wifi $@;;

--help|help) usage;;

*) ubus call network reload; wifi_updown "enable" "$2";;

esac

 

 

首先執行了scan_wifi

scan_wifi() {

local cfgfile="$1"

DEVICES=

config_cb() {

local type="$1"

local section="$2"

 

# section start

case "$type" in

wifi-device)

append DEVICES "$section"

config_set "$section" vifs ""

config_set "$section" ht_capab ""

;;

esac

 

# section end

config_get TYPE "$CONFIG_SECTION" TYPE

case "$TYPE" in

wifi-iface)

config_get device "$CONFIG_SECTION" device

config_get vifs "$device" vifs

append vifs "$CONFIG_SECTION"

config_set "$device" vifs "$vifs"

;;

esac

}

config_load "${cfgfile:-wireless}"

}

其主要執行了config_load "${cfgfile:-wireless}"即:config_load wireless

/lib/functions文件定義了config_load

config_load() {

[ -n "$IPKG_INSTROOT" ] && return 0

uci_load "$@"

}

Config_load裏面執行uci_load wireless

/lib/config/uci.sh

uci_load() {

local PACKAGE="$1"

local DATA

local RET

local VAR

 

_C=0

if [ -z "$CONFIG_APPEND" ]; then

for VAR in $CONFIG_LIST_STATE; do

export ${NO_EXPORT:+-n} CONFIG_${VAR}=

export ${NO_EXPORT:+-n} CONFIG_${VAR}_LENGTH=

done

export ${NO_EXPORT:+-n} CONFIG_LIST_STATE=

export ${NO_EXPORT:+-n} CONFIG_SECTIONS=

export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=0

export ${NO_EXPORT:+-n} CONFIG_SECTION=

fi

 

DATA="$(/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} ${LOAD_STATE:+-P /var/state} -S -n export "$PACKAGE" 2>/dev/null)"

RET="$?"

[ "$RET" != 0 -o -z "$DATA" ] || eval "$DATA"

unset DATA

 

${CONFIG_SECTION:+config_cb}

return "$RET"

}

這段最關鍵的是:

DATA="$(/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} ${LOAD_STATE:+-P /var/state} -S -n export "$PACKAGE" 2>/dev/null)"

執行完後:

Date={config wifi-device 'wifi0'

        option type 'qcawifi'

        option channel 'auto'

        option txpower 'auto'

        option bcnburst '1'

        option hwmode '11ng'

        option disabled '0'

        option country 'US'

.........

}

這句很關鍵:[ "$RET" != 0 -o -z "$DATA" ] || eval "$DATA"

這句意思是:執行date變量的內容即date變量內容的每一行都是一條執行命令:

date變量內容的第一行是:

config wifi-device 'wifi0’

表示:config是可執行的函數或命令,$1=wifi-device $2=wifi0

/lib/function中:

config () {

local cfgtype="$1"

local name="$2"

 

export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=$(($CONFIG_NUM_SECTIONS + 1))

name="${name:-cfg$CONFIG_NUM_SECTIONS}"

append CONFIG_SECTIONS "$name"

[ -n "$NO_CALLBACK" ] || config_cb "$cfgtype" "$name"

export ${NO_EXPORT:+-n} CONFIG_SECTION="$name"

export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_TYPE=$cfgtype"

}

append() {

local var="$1"

local value="$2"

local sep="${3:- }"

 

eval "export ${NO_EXPORT:+-n} -- \"$var=\${$var:+\${$var}\${value:+\$sep}}\$value\""

}

執行後可得到:

CONFIG_SECTIONS=wifi0

CONFIG_SECTIONS__TYPE=wifi-device

對於option:

如:option type 'qcawifi'

option () {

local varname="$1"; shift

local value="$*"

 

export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_${varname}=$value"

[ -n "$NO_CALLBACK" ] || option_cb "$varname" "$*"

}

執行後可得到:

CONFIG_wifi0_type=qcawifi

依據上面,所有配置文件信息在config_load執行完後,配置信息都導出到了對應shell的變量中了

我們要獲取變量信息是很容易了


主要通過以下函數獲取和設置:

config_get() {

case "$3" in

"") eval echo "\${CONFIG_${1}_${2}:-\${4}}";;

*)  eval export ${NO_EXPORT:+-n} -- "${1}=\${CONFIG_${2}_${3}:-\${4}}";;

esac

}

config_set() {

local section="$1"

local option="$2"

local value="$3"

local old_section="$CONFIG_SECTION"

 

CONFIG_SECTION="$section"

option "$option" "$value"

CONFIG_SECTION="$old_section"

}

如:

config_get disabled "$device" disabled這個命令

執行是:

eval export ${NO_EXPORT:+-n} -- "${1}=\${CONFIG_${2}_${3}:-\${4}}";;

即:

disabled =$(CONFIG_wifi_disabled)

自此:解讀就很清晰了
config_load將配置文件信息導出到shell變量中

Config_get獲取shell變量的值

Config_set設置shell變量的值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章