uci 命令:
uci help:
Usage: uci [<options>]<command> [<arguments>]
Commands:
batch
export [<config>] 導出配置文件
import [<config>] 以uci語法導入配置文件
changes [<config>] 列出配置文件分階段修改的內容(沒有commit),若未指定配置文件,則導出所有配置文件的修改
commit [<config>] 對給定的配置文件寫入修改,如果沒有指定參數則將所有的配置文件寫入文件系統
add <config><section-type> 增加指定配置文件的類型爲section-type的匿名區段
add_list <config>.<section>.<option>=<string> 對已存在的list選項增加字符串
del_list <config>.<section>.<option>=<string> 刪除已存在的list選項的字符串
show [<config>[.<section>[.<option>]]] 顯示指定的選項、配置節或配置文件
get <config>.<section>[.<option>] 獲取指定區段選項的值
set <config>.<section>[.<option>]=<value> 設置指定配置節選項的值,或者是增加一個配置節,類型設置爲指定的值
delete <config>[.<section>[[.<option>][=<id>]]] 刪除指定配置節或選項
rename <config>.<section>[.<option>]=<name> 對指定的選項或配置節重命名
revert <config>[.<section>[.<option>]] 恢復指定的選項,配置節或配置文件
reorder <config>.<section>=<position>
Options:
-c <path> 設置配置文件的搜索路徑 (default: /etc/config)
-d <str> 在uci顯示中設置列表值的分隔符 in uci show
-f <file> 使用<file>作爲輸入,而不是stdin
-m 導入時,將數據合併到現有包中
-n 名稱未命名部分導出(默認)
-N 不要命名unname dsections
-p <path> 添加配置更改文件的搜索路徑
-P <path> 添加配置更改文件的搜索路徑,並使用默認值
-q 安靜模式(不打印錯誤信息)
-s 強制嚴格模式(停止解析器錯誤,默認)
-S 停止嚴格模式
-X 不要在'show'上使用擴展語法
uci shell 接口:
/lib/config/uci.sh
uci_load #從uci文件中加載配置並設置到環境變量中
uci_set_default
uci_revert_state
uci_set_state()
uci_toggle_state
uci_set
uci_get_state #指定從/var/state中獲取狀態值
uci_get #從uci文件中獲取值
uci_add
uci_rename
uci_remove
uci_commit
/lib/functions.sh
注意:在使用“config_”開頭的函數時要先使用config_load,將配置文件載入環境變量
#在字符串前加‘:’並返回“:123”
w=debug 123
echo $w
輸出:":123"
config
#將配置節設置到環境變量中,供uci.sh調用
option
#將配置節中的選項設置到環境變量中,供uci.sh調用
list
#將配置節中的鏈表設置到環境變量中,供uci.sh調用
#config_unset
#調用config_set 清空<section>.<option>的value值
#config_unset <section> <option>
#config_load: 調用uci_load函數從配置文件中讀取配置然後設置到環境變量中
config_load <config>
#config_get:從當前環境變量中獲取配置值
# variable:用來存儲config值的變量
#section/option:要獲取節點/選項的名字
config_get <variable> <section> <option> [<default>]
#config_get_bool:從當前環境變量中獲取配置值 ,並把值轉換成整數
config_get_bool <variable> <section> <option> [<default>]
#config_set:將變量設置到環境變量中以便後續讀取(注:並未設置到配置文件中)
#section/option
#value:要爲該節點設置的值
config_set <section> <option> <value>
#config_foreach:遍歷每個section去調用callback_func函數(callback_func 的入參爲section name)
#[<section type>]:只遍歷這個類型的section......
config_foreach <callback_func> [<section type>]
#config_list_foreach:遍歷section下list的option值,並調用callback_func函數(入參爲list option的值,有多少值調用多少次)
config_list_foreach <section> <list> <callback_func>
#加載/etc/modus.d/*下面的所有模塊
insert_modules
#應用shell腳本
include <shell script> [<shell script>......]
append
list_contains
reset_cb
package
default_prerm
default_postinst
find_mtd_index
find_mtd_part
group_add
group_exists
group_add_next
group_add_user
user_add
user_exists
uci重要的結構體:
struct uci_context
{
/* list of config packages */
struct uci_list root;
/* parser context, use for error handling only */
struct uci_parse_context *pctx;
/* backend for import and export */
struct uci_backend *backend;
struct uci_list backends;
/* uci runtime flags */
enum uci_flags flags;
char *confdir;
char *savedir;
/* search path for delta files */
struct uci_list delta_path;
/* private: */
int err;
const char *func;
jmp_buf trap;
bool internal, nested;
char *buf;
int bufsz;
};
uci_context:uci上下文結構,貫徹查詢、更改配置文件全過程
struct uci_package
{
struct uci_element e;
struct uci_list sections;
struct uci_context *ctx;
bool has_delta;
char *path;
/* private: */
struct uci_backend *backend;
void *priv;
int n_section;
struct uci_list delta;
struct uci_list saved_delta;
};
uci_package:對應一個配置文件
struct uci_section
{
struct uci_element e;
struct uci_list options;
struct uci_package *package;
bool anonymous;
char *type;
};
uci_section:對應配置文件中的節
struct uci_option
{
struct uci_element e;
struct uci_section *section;
enum uci_option_type type;
union {
struct uci_list list;
char *string;
} v;
};
uci_option:對應配置文件節中的option和list
struct uci_ptr
{
enum uci_type target;
enum {
UCI_LOOKUP_DONE = (1 << 0),
UCI_LOOKUP_COMPLETE = (1 << 1),
UCI_LOOKUP_EXTENDED = (1 << 2),
} flags;
struct uci_package *p;
struct uci_section *s;
struct uci_option *o;
struct uci_element *last;
const char *package;
const char *section;
const char *option;
const char *value;
};
uci_ptr:元素位置指針結構,用以查詢並保存對應的位置元素
uci API:
/usr/local/include/uci.h
/**
*uci_alloc_context: Allocate a new uci context
*動態申請一塊內存用於struct uci_context結構。
*/
extern struct uci_context * uci_alloc_context(void);
/**
*uci_alloc_alternate_context: Allocate new uci context with specific default
*/
extern struct uci_context*uci_alloc_alternate_context(const char *confdir, const char *savedir);
/**
*uci_free_context: Free the uci context including all of its data
*釋放struct uci_context結構內存,以及爲其成員申請的所有內存
*/
extern void uci_free_context(structuci_context *ctx);
/**
*uci_perror: Print the last uci error that occured
*@ctx: uci context
*@str: string to print before the error message
*打印最後一條出錯信息,如果在打印出錯信息前想打印其他信息,則傳入str即可
*/
extern void uci_perror(struct uci_context*ctx, const char *str);
/**
*uci_geterror: Get an error string for the last uci error
*獲取最後一個uci錯誤的錯誤字符串
*@ctx: uci context
*@dest: target pointer for the string
*@str: prefix for the error message
*
*Note: string must be freed by the caller
*/
extern void uci_get_errorstr(structuci_context *ctx, char **dest, const char *str);
/**
*uci_import: Import uci config data from a stream
*從文件流中導入uci的配置數據
*@ctx: uci context
*@stream: file stream to import from
*@name: (optional) assume the config has the given name
*@package: (optional) store the last parsed config package in this variable
*@single: ignore the 'package' keyword and parse everything into a singlepackage
*
*the name parameter is for config files that don't explicitly use the 'package<...>' keyword
* if'package' points to a non-null struct pointer, enable delta tracking and merge
*/
extern int uci_import(struct uci_context * ctx, FILE * stream, const char *name, struct uci_package **package, boolsingle);
/**
*uci_export: Export one or all uci config packages
*導出uci的配置文件數據到文件流stream
*@ctx: uci context
*@stream: output stream
*@package: (optional) uci config package to export
*@header: include the package header
*/
extern int uci_export(struct uci_context*ctx, FILE *stream, struct uci_package *package, bool header);
/**
*uci_load: Parse an uci config file and store it in the uci context
*解析一個uci配置文件並把它存到ctx中
*@ctx: uci context
*@name: name of the config file (relative to the config directory)
*@package: store the loaded config package in this variable
*/
extern int uci_load(struct uci_context*ctx, const char *name, struct uci_package **package);
/**
*uci_unload: Unload a config file from the uci context
*從ctx中卸載一個配置文件包
*@ctx: uci context
*@package: pointer to the uci_package struct
*/
extern int uci_unload(struct uci_context*ctx, struct uci_package *p);
/**
*uci_lookup_ptr: Split an uci tuple string and look up an element tree
*分離一個uci類型的字符串元組,且查找對應的元素樹
*@ctx: uci context
*@ptr: lookup result struct
*@str: uci tuple string to look up
*@extended: allow extended syntax lookup
*
* ifextended is set to true, uci_lookup_ptr supports the following
*extended syntax:
*
*Examples:
* network.@interface[0].ifname ('ifname' option of the first interfacesection)
* network.@interface[-1] (lastinterface section)
*Note: uci_lookup_ptr will automatically load a config package if necessary
*@str must not be constant, as it will be modified and used for the stringsinside @ptr,
*thus it must also be available as long as @ptr is in use.
*
*This function returns UCI_ERR_NOTFOUND if the package specified in the tuple
*string cannot be found. Otherwise itwill return UCI_OK.
*
*Note that failures in looking up other parts, if they are also specfied,
*including section and option, will also have a return value UCI_OK but with
*ptr->flags * UCI_LOOKUP_COMPLETE not set.
*/
extern int uci_lookup_ptr(structuci_context *ctx, struct uci_ptr *ptr, char *str, bool extended);
/**
*uci_add_section: Add an unnamed section
*添加一個匿名節點
*@ctx: uci context
*@p: package to add the section to
*@type: section type
*@res: pointer to store a reference to the new section in
*/
extern int uci_add_section(structuci_context *ctx, struct uci_package *p, const char *type, struct uci_section**res);
/**
*uci_set: Set an element's value; create the element if necessary
*設置一個元素值,必要的話新建這個元素
*@ctx: uci context
*@ptr: uci pointer
*
*The updated/created element is stored in ptr->last
*/
extern int uci_set(struct uci_context *ctx,struct uci_ptr *ptr);
/**
*uci_add_list: Append a string to an element list
*附加一個字符串到一個元素列表
*@ctx: uci context
*@ptr: uci pointer (with value)
*
*Note: if the given option already contains a string value,
* itwill be converted to an 1-element-list before appending the next element
*/
extern int uci_add_list(struct uci_context*ctx, struct uci_ptr *ptr);
/**
*uci_del_list: Remove a string from an element list
*從一個元素列表中刪除一個元素
*@ctx: uci context
*@ptr: uci pointer (with value)
*
*/
extern int uci_del_list(struct uci_context*ctx, struct uci_ptr *ptr);
/**
*uci_reorder: Reposition a section
*改變一個節的(順序)位置
*@ctx: uci context
*@s: uci section to reposition
*@pos: new position in the section list
*/
extern int uci_reorder_section(structuci_context *ctx, struct uci_section *s, int pos);
/**
*uci_rename: Rename an element
*重命名一個元素
*@ctx: uci context
*@ptr: uci pointer (with value)
*/
extern int uci_rename(struct uci_context*ctx, struct uci_ptr *ptr);
/**
*uci_delete: Delete a section or option
*刪除一個節或選項
*@ctx: uci context
*@ptr: uci pointer
*/
extern int uci_delete(struct uci_context*ctx, struct uci_ptr *ptr);
/**
*uci_save: save change delta for a package
*爲一個package保存改變的delta
*@ctx: uci context
*@p: uci_package struct
*/
extern int uci_save(struct uci_context*ctx, struct uci_package *p);
/**
*uci_commit: commit changes to a package
*提交改動到一個package
*@ctx: uci context
*@p: uci_package struct pointer
*@overwrite: overwrite existing config data and flush delta
*
*committing may reload the whole uci_package data,
*the supplied pointer is updated accordingly
*/
extern int uci_commit(struct uci_context*ctx, struct uci_package **p, bool overwrite);
/**
*uci_list_configs: List available uci config files
*列出可用的uci配置文件
*@ctx: uci context
*
*caller is responsible for freeing the allocated memory behind list
*/
extern int uci_list_configs(structuci_context *ctx, char ***list);
/**
*uci_set_savedir: override the default delta save directory
*覆蓋默認的delta保存的目錄
*@ctx: uci context
*@dir: directory name
*
*This will also try adding the specified dir to the end of delta pathes.
*/
extern int uci_set_savedir(structuci_context *ctx, const char *dir);
/**
*uci_set_confdir: override the default config storage directory
*覆蓋默認的配置文件存儲目錄
*@ctx: uci context
*@dir: directory name
*/
extern int uci_set_confdir(structuci_context *ctx, const char *dir);
/**
*uci_add_delta_path: add a directory to the search path for change delta files
*爲detal文件添加一個目錄到搜索路徑
*@ctx: uci context
*@dir: directory name
*
*This function allows you to add directories, which contain 'overlays'
*for the active config, that will never be committed.
*
*Adding a duplicate directory will cause UCI_ERR_DUPLICATE be returned.
*/
extern int uci_add_delta_path(structuci_context *ctx, const char *dir);
/**
*uci_revert: revert all changes to a config item
*恢復一個配置項的所有變更
*@ctx: uci context
*@ptr: uci pointer
*/
extern int uci_revert(struct uci_context*ctx, struct uci_ptr *ptr);
/**
*uci_parse_argument: parse a shell-style argument, with an arbitrary quotingstyle
*解析一個shell風格的參數
*@ctx: uci context
*@stream: input stream
*@str: pointer to the current line (use NULL for parsing the next line)
*@result: pointer for the result
*/
extern int uci_parse_argument(structuci_context *ctx, FILE *stream, char **str, char **result);
/**
*uci_set_backend: change the default backend
*@ctx: uci context
*@name: name of the backend
*
*The default backend is "file", which uses /etc/config for configstorage
*/
extern int uci_set_backend(structuci_context *ctx, const char *name);
/**
*uci_validate_text: validate a value string for uci options
*驗證uci options中的一個字符串值
*@str: value
*
*this function checks whether a given string is acceptable as value
*for uci options
*/
extern bool uci_validate_text(const char*str);
/**
*uci_parse_ptr: parse a uci string into a uci_ptr
*解析一個uci字符串到uci_prt結構中
*@ctx: uci context
*@ptr: target data structure
*@str: string to parse
*
*str is modified by this function
*/
int uci_parse_ptr(struct uci_context *ctx,struct uci_ptr *ptr, char *str);
/**
* uci_lookup_next:lookup a child element
*查找子元素
*@ctx: uci context
*@e: target element pointer
*@list: list of elements
*@name: name of the child element
*
* ifparent is NULL, the function looks up the package with the given name
*/
int uci_lookup_next(struct uci_context*ctx, struct uci_element **e, struct uci_list *list, const char *name);
/**
*uci_parse_section: look up a set of options
*查找一組選項
*@s: uci section
*@opts: list of options to look up
*@n_opts: number of options to look up
*@tb: array of pointers to found options
*/
void uci_parse_section(struct uci_section*s, const struct uci_parse_option *opts,
int n_opts, struct uci_option **tb);
/**
*uci_hash_options: build a hash over a list of options
*在選項列表上構建一個散列
*@tb: list of option pointers
*@n_opts: number of options
*/
uint32_t uci_hash_options(struct uci_option**tb, int n_opts);
/**
*uci_alloc_element: allocate a generic uci_element, reserve a buffer andtypecast
*分配一個通用的uci_element,保留緩衝區和屬性
*@ctx: uci context
*@type: {package,section,option}
*@name: string containing the name of the element
*@datasize: additional buffer size to reserve at the end of the struct
*/
#define uci_alloc_element(ctx, type, name,datasize) \
uci_to_## type (uci_alloc_generic(ctx, uci_type_ ## type, name, sizeof(struct uci_ ##type) + datasize))
#define uci_dataptr(ptr) \
(((char*) ptr) + sizeof(*ptr))
/**
*uci_lookup_package: look up a package
*查找package
*@ctx: uci context
*@name: name of the package
*/
static inline struct uci_package *
uci_lookup_package (struct uci_context *ctx,const char *name)
{
structuci_element *e = NULL;
if(uci_lookup_next(ctx, &e, &ctx->root, name) == 0)
return uci_to_package(e);
else
return NULL;
}
/**
*uci_lookup_section: look up a section
*查找section
*@ctx: uci context
*@p: package that the section belongs to
*@name: name of the section
*/
static inline struct uci_section *
uci_lookup_section(struct uci_context *ctx,struct uci_package *p, const char *name)
{
structuci_element *e = NULL;
if(uci_lookup_next(ctx, &e, &p->sections, name) == 0)
returnuci_to_section(e);
else
returnNULL;
}
/**
*uci_lookup_option: look up an option
*查找option
*@ctx: uci context
*@section: section that the option belongs to
*@name: name of the option
*/
static inline struct uci_option *
uci_lookup_option(struct uci_context *ctx,struct uci_section *s, const char *name)
{
structuci_element *e = NULL;
if(uci_lookup_next(ctx, &e, &s->options, name) == 0)
returnuci_to_option(e);
else
returnNULL;
}
static inline const char *
uci_lookup_option_string(struct uci_context*ctx, struct uci_section *s, const char *name)
{
structuci_option *o;
o= uci_lookup_option(ctx, s, name);
if(!o || o->type != UCI_TYPE_STRING)
returnNULL;
returno->v.string;
}