SHIHUC

好记性不如烂笔头,还可以分享给别人看看! 专注基础算法,互联网架构,人工智能领域的技术实现和应用。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

openstack(liberty): devstack中的iniset/iniget函数分析

Posted on 2016-01-27 14:52  shihuc  阅读(500)  评论(0编辑  收藏  举报

这个ini开头的函数在devstack的启动配置中用的非常多,他主要负责.ini文件的配置,这个过程包括对相关ini文件的添加,注释,删除,获取信息,多行信息获取等。

这里主要说的iniset和iniget函数在devstack/inc/ini-config文件里面。

iniset具体函数内容:

 1 # Set an option in an INI file
 2 # iniset [-sudo] config-file section option value
 3 #  - if the file does not exist, it is created
 4 function iniset {
 5     local xtrace=$(set +o | grep xtrace)
 6     set +o xtrace
 7     local sudo=""
 8     if [ $1 == "-sudo" ]; then
 9         sudo="sudo "
10         shift
11     fi
12     local file=$1
13     local section=$2
14     local option=$3
15     local value=$4
16 
17     if [[ -z $section || -z $option ]]; then
18         $xtrace
19         return
20     fi
21 
22     if ! grep -q "^\[$section\]" "$file" 2>/dev/null; then
23         # Add section at the end
24         echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
25     fi
26     if ! ini_has_option "$file" "$section" "$option"; then
27         # Add it
28         $sudo sed -i -e "/^\[$section\]/ a\\
29 $option = $value
30 " "$file"
31     else
32         local sep=$(echo -ne "\x01")
33         # Replace it
34         $sudo sed -i -e '/^\['${section}'\]/,/^\[.*\]/ s'${sep}'^\('${option}'[ \t]*=[ \t]*\).*$'${sep}'\1'"${value}"${sep} "$file"
35     fi
36     $xtrace
37  }                

上面28-29两行,表示在以[$section]开头的行后面添加一行,这行的内容为"$option = $value"。注意,这里要用真实值替换,即$option和$value的真实值。主要是 a\选项的使用。

第34行,表示替换当前以后的section中option对应的值。具体含义是在$file文件中,将[$section]与下一个“[”开头的任意section(“]"结尾)之间的内容中,$option = 任意值,替换为$option = $value. 注意,$option与=号之间可以有任意多个空格,这个空格可以是space或者tab产生的。

 

下面说说iniget函数,代码如下:

 1 # Get an option from an INI file
 2 # iniget config-file section option
 3 function iniget {
 4     local xtrace=$(set +o | grep xtrace)
 5     set +o xtrace
 6     local file=$1
 7     local section=$2
 8     local option=$3
 9     local line
10 
11     line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
12     echo ${line#*=}
13     $xtrace
14 }

这个函数的主要内容,就是将$file中,找到[$section]与下一个方括号代表的section之间以$option =开头的行的内容,并打印输出给变量line,注意,$option与=号之间可以有任意多个space或tab空格。然后echo输出line中=之后的内容。

 

理解上面两个函数后,就很容易了解ini配置文件的操作了。比如/etc/neutron/dhcp_agent.ini。ini文件的操作,重要的是要有一些sed的相关知识。

 

sed使用格式: 

Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...

option内容如下

-n, --quiet, --silent
  suppress automatic printing of pattern space
-e script, --expression=script
  add the script to the commands to be executed
-f script-file, --file=script-file
  add the contents of script-file to the commands to be executed
--follow-symlinks
  follow symlinks when processing in place
-i[SUFFIX], --in-place[=SUFFIX]
  edit files in place (makes backup if SUFFIX supplied)
-c, --copy
  use copy instead of rename when shuffling files in -i mode
-b, --binary
  does nothing; for compatibility with WIN32/CYGWIN/MSDOS/EMX (
  open files in binary mode (CR+LFs are not treated specially))
-l N, --line-length=N
  specify the desired line-wrap length for the `l' command
--posix
  disable all GNU extensions.
-r, --regexp-extended
  use extended regular expressions in the script.
-s, --separate
  consider files as separate rather than as a single continuous
  long stream.
-u, --unbuffered
  load minimal amounts of data from the input files and flush
  the output buffers more often
-z, --null-data
  separate lines by NUL characters
--help
  display this help and exit
--version
  output version information and exit

 

下面备注一些主要的sed命令,这些命令可以用在script中,请参考上面两个函数:

命令  功能
 a\

 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行

 c\  用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行
 i\  在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行
 d  删除行
 h  把模式空间里的内容复制到暂存缓冲区
 H  把模式空间里的内容追加到暂存缓冲区
 g  把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容
 G  把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面
 l  列出非打印字符
 p  打印行
 n  读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理
 q  结束或退出sed
 r  从文件中读取输入行
 !  对所选行以外的所有行应用命令
 s  用一个字符串替换另一个
 g  在行内进行全局替换
   
 w  将所选的行写入文件
 x  交换暂存缓冲区与模式空间的内容
 y  将字符替换为另一字符(不能对正则表达式使用y命令)