一个修改配置文件的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"
时间: 2024-08-10 01:25:56

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

【原】Linux shell script 2>&1是什么意思

先说结论, 2>&1 的意思是,把标准错误(stderr)重定向到标准输出(stdout) 如果想了解为什么,可以继续阅读: 1和2 是什么 shell中,有一些常用的文件描述符(file descriptor): 0: 标准输入(stdin) 1: 标准输出(stdout) 2: 标准错误(stderr) 所以 2>&1 中的2就是标准错误,1就是标准输出. > 符号是什么 ">" 是shell中的重定向符, 例如:echo "abc

linux shell script: Basic concept01 - String

basic concept01: String本文所有的测试例如无特殊说明,均based on fish shell 就从字符串说起吧,啥是字符串就不用解释了,我们来看几个简单的例子 ?> ~ set param abc ?> ~ echo "string with blank and $param surrounded with double quotation marks" string with blank and abc surrounded with double

Linux shell Script初识

shell secript: 执行方式的差异: ./ sh执行都是在创建一个子程序来执行,只会继承环境变量, 其中的变量如果export声明,子程序的子程序会继承,不会升级为环境变量 source 的执行方式是把脚本放到父程序的环境执行, 其中的变量如果export声明,会升级成环境变量 test判断,[]判断是一样的,建议使用[]的判断方式 默认变量($0, $1......) $0,$1....位置变量,代表参数 $#:代表参数的个数 [email protected]:代表参数"$1&qu

1>>linux shell script编程

Studying book is <Linux Command Line and Shell Scripting Bible> by Richard Blum and Christine Bresnahan. Thanks. If I have enough time,I will improve this note. Now,I'm coding.

linux shell脚本

定义: linux shell script是一组shell命令组成的批处理文件.类似于windows的bat文件. shell脚本基本语法 每当读取到一个ENTER符号,就开始尝试执行该行的命令. 如果一行的命令太长,可以在行尾使用反斜杠\将命令延续到下一行. [[email protected] testsh]# cat testenter.sh echo zjf is a good man #开头代表注释. 脚本的执行 脚本的执行方式在前几篇文章里有叙述.这里要重点关注这点: sh和./的

Linux shell脚本基础学习详细介绍(完整版)二

详细介绍Linux shell脚本基础学习(五) Linux shell脚本基础前面我们在介绍Linux shell脚本的控制流程时,还有一部分内容没讲就是有关here document的内容这里继续. Linux shell脚本基础已经被分成好几个部分了,这里对控制流程的内容也就马上讲完了,这是最后一部分关于here document,这里举例稍微有点复杂,我们慢慢来分析这个复杂Linux shell脚本. 6. Here documents 当要将几行文字传递给一个命令时,here docu

第一个shell脚本——修改配置文件

有需求,可以让自己偷懒才是学习的真正动力.由于测试环境在构建代码之后总是需要手动修改配置文件,因此边学习边完成了一个shell脚本,可以一键修改. 定义了一个函数,输出信息以绿色字体显示. function echo_green { echo -e "\033[32m$1\033[0m" } 输出提示信息 echo_green "是否一键修改xxx?(y/n)" 读取键盘输入 read answer 要修改的配置文件有两类:一类是明确清楚应该修改哪些字符串,直接用替

CentOS Linux下一个tomcat起停,查看日志的shell script

CentOS 的tomcat安装目录:/usr/local/tomcat vi MyTomcatUitl.sh          创建文件chmod u+x MyTomcatUtil.sh   赋执行权限 shell script : 1 #!/bin/bash 2 3 # tomcat启动,停止,日志显示脚本 4 5 if [ $1 == ''];then 6 echo "请带一个参数执行命令:start 启动tomcat,stop 停止tomcat , logs 查看tomcat动态日志&q

Linux shell 的一个fork炸弹

.(){ .|.& };.  或者  :(){ :|:& };: 这13个字符由Jaromil ,在 2002 年设计了最为精简的一个 fork炸弹的实现. .()  说明下面要定义一个函数,函数名为小数点,没有可选参数:{    表示函数体的开始:.|.& 表示函数体真正要做的事情,首先它递归使用本函数,然后李永贵管道调用一个新进程(它要做的事情也是递归调用本函数),并将其放到后台执行.}    表示函数体的结束:;    并不会执行什么操作,在命令行中用来分隔两个命令用.从总体