linux shell脚本读取配置文件 val=1,一个修改配置文件的linux shell script

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

现在,需要通过web界面给用户留出接口来修改类似配置文件,大的方法是从php调用linux shell script,于是,现在贴一个可以修改此种配置文件的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个大的方面:数据库,业务,离线;每个unit有属于自己的字段名及字段值。

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

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

要做到修改配置文件的功能其实并不难,20-30行便可以解决问题。但是基于“一切输入都是有害的”的原则,需要在shell中加入各种容错处理,如果用户参数输入错误,要能及时提醒用户,定位问题所在,下面是基于这样一个初衷的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-30-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 "\n" "\ ")

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

其中,第一行表示找到BUSINESS这个unit所在的行号区间,注意是开区间;第二行表示所有匹配到field行号,因为可能多个unit中有相同的field;第三行表示最终落入unit区间的field行号;第四行表示所在行修改后的结果。

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

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-30-yg/yg-soft"

CONFIG_FILE="$MY_HOME/config.ini"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值