一個修改配置文件的linux shell script
來源:程序員人生 發布時間:2014-11-04 09:01:01 閱讀次數:3446次
不久之前,曾搜到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.vxbq.cn/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"
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈