程序员人生 网站导航

一个修改配置文件的linux shell script

栏目:互联网时间:2014-11-04 09:01:01

不久之前,曾搜到1篇博客是读取配置文件的,http://www.cnblogs.com/bo083/archive/2012/11/19/2777076.html,用到现在,感觉10分方便,感谢作者。

现在,需要通过web界面给用户留出接口来修改类似配置文件,大的方法是从php调用linux shell script,因而,现在贴1个可以修改此种配置文件的linux shell。

首先,配置文件的格式以下:

[unit1] field1=value1 field2=value2 [unit2] field1=value3 field3=value4 ... ...

例子以下,config.ini:

[DATABASE] dbms_ip=localhost user=root passwd=cloud db_name=cloud port=2394 [BUSINESS] port=9084 [OFFLINE] pcap_file=test.pcap

配置文件中包括3个unit,表示3个大的方面:http://www.wfuyu.com/db/,业务,离线;每一个unit有属于自己的字段名及字段值。


上文中援用博客正是能读取这样的配置文件,而目前我们便是要通过linux shell来修改这个配置文件。

我们设计的程序名为 modify_config_file,使用 ./modify_config_file unit1-field1=changed_value1 unit2-field1=changed_value2 这样的格式(参数可以继续添加)来进行修改。

要做到修改配置文件的功能其实其实不难,20⑶0行即可以解决问题。但是基于“1切输入都是有害的”的原则,需要在shell中加入各种容错处理,如果用户参数输入毛病,要能及时提示用户,定位问题所在,下面是基于这样1个初衷的shell,固然,名称为modify_config_file:

#!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin export PATH #Program # This program is to modify the configuration file #History # 2014.10.30 WeiZheng 1.1 MY_HOME="/home/weizheng/10⑶0-yg/yg-soft" CONFIG_FILE="$MY_HOME/config.ini" ERROR_NUM=255 function get_line_num() { # Check if the argument name has the separator "-" that separate the argument unit and argument field separator=$(echo $1 | grep "-") if [ -z "$separator" ]; then echo -e "error: "$1": argument name has no separator "-" that separate the argument unit and argument field" exit $ERROR_NUM fi # Check if the argument name has argument unit and argument field arg_unit=$(echo $1 | cut -d "-" -f 1) arg_field=$(echo $1 | cut -d "-" -f 2) if [ -z "$arg_unit" -o -z "$arg_field" ]; then echo -e "error: "$1": argument name has no argument unit or argument field around "-"" exit $ERROR_NUM fi # Get the argument unit's interval [$arg_unit_line_num, $next_neighbour_unit_line_num) arg_unit_line_num=$(grep -n "[$arg_unit]" $CONFIG_FILE | cut -d ":" -f1) if [ -z "$arg_unit_line_num" ]; then echo -e "error: "$arg_unit": can not find argument unit" exit $ERROR_NUM fi next_neighbour_unit_line_num=$(awk "NR>$arg_unit_line_num && /^[.*]/ {print NR; exit 0}" $CONFIG_FILE) if [ -z "$next_neighbour_unit_line_num" ]; then file_line_count=$(wc -l $CONFIG_FILE | cut -d " " -f 1) next_neighbour_unit_line_num=$((file_line_count+1)) fi echo "argument unit interval: ($arg_unit_line_num, $next_neighbour_unit_line_num)" arg_field_line_nums=$(grep -n "^$arg_field=" $CONFIG_FILE | cut -d ":" -f1 | tr " " " ") if [ -z "$arg_field_line_nums" ]; then echo -e "error: "$arg_field": can not find argument field" exit $ERROR_NUM fi echo "matched argument field in line: $arg_field_line_nums" # the $arg_field_line_num must in the interval ($arg_unit_line_num, $next_neighbour_unit_line_num) for arg_field_line_num in $arg_field_line_nums do if [ $arg_field_line_num -gt $arg_unit_line_num -a $arg_field_line_num -lt $next_neighbour_unit_line_num ]; then echo "find argument field in line: $arg_field_line_num" return $arg_field_line_num fi done # if not return in for-loop, the arg_field_line_num is not in the interval ($arg_unit_line_num, $next_neighbour_unit_line_num) echo -e "the argument field is not in the argument unit interval" exit $ERROR_NUM } while [ "$1" ] do # Check if the separator "=" that separate the argument name and argument value exists equal_symbol=$(echo $1 | grep "=") if [ -z "$equal_symbol" ]; then echo -e "error: "$1": argument has no "="" exit $ERROR_NUM fi # Check if argument name and argument value exist arg_name=$(echo $1 | cut -d "=" -f 1) arg_value=$(echo $1 | cut -d "=" -f 2) if [ -z "$arg_name" -o -z "$arg_value" ]; then echo -e "error: "$1": argument has no name or value around "="" exit $ERROR_NUM fi # Get the line number of the argument from CONFIG_FILE get_line_num $arg_name args_line_num=$? # use sed change the argument line arg_field=$(echo $arg_name | cut -d "-" -f 2) sed -i "${args_line_num}c $arg_field=$arg_value" $CONFIG_FILE new_line=$(sed -n "${args_line_num}p" $CONFIG_FILE) echo "the argument has been changed: $new_line" shift 1 done

用户通过以下命令修改配置:

./modify_config_file BUSINESS-port=8888
输出以下:

argument unit interval: (8, 11) matched argument field in line: 6 9 find argument field in line: 9 the argument has been changed: port=8888

其中,第1行表示找到BUSINESS这个unit所在的行号区间,注意是开区间;第2行表示所有匹配到field行号,由于可能多个unit中有相同的field;第3行表示终究落入unit区间的field行号;第4行表示所在行修改后的结果。

另外,用户输入不符合格式是很有可能,针对以下几种毛病都会报告并且定位:

1. ./modify_config_file BUSINESS error: "BUSINESS": argument has no "=" 2. ./modify_config_file BUSINESS= error: "BUSINESS=": argument has no name or value around "=" 3. ./modify_config_file BUSINESS=8888 error: "BUSINESS": argument name has no separator "-" that separate the argument unit and argument field 4. ./modify_config_file BUSINESS-=8888 error: "BUSINESS-": argument name has no argument unit or argument field around "-" 5. ./modify_config_file BUSINESS-por=8888 argument unit interval: (8, 11) error: "por": can not find argument field 6. ./modify_config_file BUSINE-port=8888 error: "BUSINE": can not find argument unit

如果要利用到其它的配置文件,需要在脚本中修改配置文件所在路径与文件名:

MY_HOME="/home/weizheng/10⑶0-yg/yg-soft" CONFIG_FILE="$MY_HOME/config.ini"
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐