Linux下使用脚本读取参数修改配置文件


概述

  • 在Linux下经常会遇到需要使用脚本来自动修改配置文件内容的需求,针对这种情况,特别整理了这样几种可以使用的方式方法。(以下几种方式由简入难)
  • 1、清空目标文件并将新内容写入文件并保存。
  • 2、向目标文件中追加新的内容并保存。
  • 3、传参指定修改内容将目标文件中指定内容进行修改并保存。
  • 4、将传递参数修改为一个配置文件,每次执行时默认读取配置文件根据区中的内容修改对应的文件信息。
  • 5、添加条件判断,满足条件时执行4的操作。
  • 注:下面开始实现上述要求的方式方法,约定以下几个文件和文件名:/cfg/target.t(目标文件,/cfg为路径)、/cmd/cmd.sh(执行的shell脚本,/cmd为路径)、cmd.cfg(执行shell脚本相应的配置文件)
  • 文件目录参考:
.
└── cfg_demo
    ├── cfg(修改目标目录)
    │   ├── bak_target.t(备份的目标文件)
    │   └── target.t(目标文件)
    └── cmd(shell脚本目录)
        ├── cmd.cfg(shell脚本对应的配置文件)
        └── cmd.sh(shell脚本)

3 directories, 4 files

清空目标文件并将新内容写入文件并保存。

  • 用到的命令有
:>${target_file}; #清空目标文件内容
cat ${cmd_cfg} > ${target_file} #使用cat命令将配置文件内容取出重定向到目标文件中
  • 当前目标文件target.t文件中的内容如下:
# interfaces(5) file used by ifup(8) and ifdown(8)
auto eno1
iface eno1 inet dhcp
pre-up ifconfig eno1:0 192.168.0.139
up ifconfig eno1:0 192.168.0.139

auto lo
iface lo inet loopback

  • 执行如下shell命令情况目标文件并将设置好的内容填充进空文件中并保存。
#!/bin/bash
target_file=../cfg/target.t

echo "start clear target file message!"
:>${target_file}; #清空目标文件内容
echo "clear end."

echo "start input message to target file."
#	逐行将内容插入目标文件中
echo "auto eno1" >> ${target_file};
echo "iface eno1 inet dhcp" >> ${target_file};
echo "pre-up ifconfig eno1:0 192.168.0.111" >> ${target_file};
echo "up ifconfig eno1:0 192.168.0.111" >> ${target_file};
echo "new file message input end."
echo "please look over target file"

在这里插入图片描述

  • 从上面打印信息及最后查看的结果能看出是可以这么做的,但是有点蠢啊。
  • 而且内容是写死的。顺便实现了将cmd.cfg的内容放到目标文件中的功能。脚本内容如下:
  • 使用cat命令将配置文件内容取出重定向到目标文件中
#!/bin/bash
target_file=../cfg/target.t
cmd_cfg=./cmd.cfg

echo "start clear target file message!"
:>${target_file};
echo "clear end."

echo "start input message to target file."
cat ${cmd_cfg} > ${target_file} #使用cat命令将配置文件内容取出重定向到目标文件中
echo "please look over target file"

在这里插入图片描述

向目标文件中追加新的内容并保存。

  • 追加内容只需要使用>>追加重定向即可。
  • shell脚本内容如下:
#!/bin/bash
target_file=../cfg/target.t
cmd_cfg=./cmd.cfg

echo "start append message to target file."
cat ${cmd_cfg} >> ${target_file}	#追加重定向到目标文件
echo "please look over target file"

在这里插入图片描述

传参指定修改内容将目标文件中指定内容进行修改并保存。

  • 这个需求就有点难度了,首先需要传递K-V参数给脚本,脚本读取K-V参数对到目标文件中将K对应的参数修改为传递的参数V即可。
  • 此外还有一种可能是传递参数为将指定字符串替换为新的字符串。
  • 针对以上两种情况分别进行两种不同的脚本。

传递K-V参数给脚本进行修改目标文件中的指定V值。

  • 查询目标文件某一行并替换
sed -i "s/^.*${key}.*$/${key}=${value}/" ${target_file}
  • shell脚本接受K-V参数方式:
while getopts ":k:v:" opt
do
    case $opt in
        k)
        echo "参数key的值$OPTARG"
        key=$OPTARG
        ;;
        v)
        echo "参数value的值$OPTARG"
        value=$OPTARG
        ;;
        ?)
        echo "未知参数"
        exit 1;;
    esac
done

echo "参数key的值$key"
echo "参数value的值$value"

在这里插入图片描述

  • 将目标文件修改为以下配置文件格式的内容:
serverip=192.168.0.1
serverport=8899
addrip=192.168.0.122
addrport=6666
  • shell脚本内容为:
#!/bin/bash
target_file=../cfg/target.t
cmd_cfg=./cmd.cfg

echo "start append message to target file."
echo "please look over target file"
while getopts ":k:v:" opt
do
    case $opt in
        k)
            echo "参数key的值$OPTARG"
            key=$OPTARG
            ;;
        v)
            echo "参数value的值$OPTARG"
            value=$OPTARG
            ;;
        ?)
            echo "please input"
            echo "./cmd.sh -k key -v value"
            exit 1;;
    esac
done

sed -i "s/^.*${key}.*$/${key}=${value}/" ${target_file}
echo "replace success."

在这里插入图片描述

传递old-string和new-string将目标文件中old-string内容进行替换。

  • 使用sed命令:
sed -i "s/$1/$2/g" ${target_file} # 将target_file目标文件中的$1字符串替换成$2字符串
  • 使用方式为
./cmd.sh old-string new-string
  • 脚本内容如下:
#!/bin/bash
target_file=../cfg/target.t
cmd_cfg=./cmd.cfg

echo "start append message to target file."
sed -i "s/$1/$2/g" ${target_file}
echo "please look over target file"

在这里插入图片描述

将传递参数修改为一个配置文件,每次执行时默认读取配置文件根据区中的内容修改对应的文件信息。

  • 这里的需求比前一步多了一个读取配置文件中的K-V对的值。只需要循环执行上一步的流程即可。读取K-V对的方式有两种,如下:
  •   第一种方式:
    
IFS='='
while read k v
do
    echo "$k : $v"
done < ${cmd_cfg}

  •   第二种方式:
    
while read line
do
    k=${line%=*}
    v=${line#*=}

    echo "$k : $v"
done < ${cmd_cfg}
  •   两种方法都可以使用。
    
  • 执行脚本内容为:

#!/bin/bash
target_file=../cfg/target.t
cmd_cfg=./cmd.cfg

IFS='='
while read k v
do
    echo "$k : $v"
done < ${cmd_cfg}

while read line
do
    key=${line%=*}
    value=${line#*=}

    echo "$key : $value"
    sed -i "s/^.*${key}.*$/${key}=${value}/" ${target_file}
done < ${cmd_cfg}

echo "replace success."

在这里插入图片描述

添加条件判断,满足条件时执行5的操作。

  • 条件判断的话只不过是进行一下shell脚本的条件执行语句即可,目前做的是判断当前目录下有没有cmd.cfg文件,如果有的话就读取其中的参数替换目标文件中的对应参数即可。

  • 执行脚本内容如下:

#!/bin/bash
target_file=../cfg/target.t
cmd_cfg=./cmd.cfg

if [ -f ${cmd_cfg} ];then
    echo "cfg file yes."
    while read line
    do
        key=${line%=*}
        value=${line#*=}
        echo "$key : $value"
        sed -i "s/^.*${key}.*$/${key}=${value}/" ${target_file}
    done < ${cmd_cfg}
    echo "replace success."
else
    echo "cfg file is no."
fi

在这里插入图片描述

补充知识

条件判断

表达式 实例
[ expression ] [ 1 -eq 1 ]
[[ expression ]] [[ 1 -eq 1 ]]
test expression test 1 -eq 1 ,等同于[]
  • 注意:括号中的表达式前后都有空格,否则会报错!
╭─[email protected] ~  
╰─➤  [ 1 -eq 1 ] && echo "true" || echo "false"
true
╭─[email protected] ~  
╰─➤  [ 1 -eq 2 ] && echo "true" || echo "false"
false
╭─[email protected] ~  
╰─➤  [1 -eq 2] && echo "true" || echo "false" 
zsh: bad pattern: [1

整数比较符

比较符 描述 实例
-eq, equal 等于 [ 1 -eq 1 ] 为true
-ne, not equal 不等于 [ 1 -ne 1 ] 为false
-gt, greate than 大于 [ 1 -gt 1 ] 为false
-lt, lesser than 小于 [ 1 -lt 1 ] 为false
-ge, greate or equal 大于或者等于 [ 1 -ge 1 ] 为true
-le, lesser or equal 小于或者等于 [ 1 -le 1 ] 为true

字符串比较符

运算符 描述 实例
== 等于 [ “a” == “a” ] 为true
!= 不等于 [ “a” != “a” ] 为false
-n 字符串长度不等于 0 为真 VAR1=1;VAR2=””,[ -n “ V A R 1 ] t r u e [ n VAR1” ]为 true,[ -n “ VAR2” ]为 false
-z 字符串长度等于 0 为真 VAR1=1;VAR2=””,[ -z “ V A R 1 ] f a l s e [ z VAR1” ]为false,[ -z “ VAR2” ]为 true
  • 注意:使用-n 判断字符串长度时,变量要加双引号,养成好习惯,字符串比较时都加上双引号

文件测试

测试符 描述 实例
-e 文件或者目录存在为真 [ -e path ] path 存在为 true
-f 文件存在为真 [ -f file_path ] 文件存在为 true
-d 目录存在为真 [ -d dir_path ] 目录存在为 true
-r 有读权限为真 [ -r file_path ]file_path有读权限为真
-w 有写权限为真 [ -w file_path ]file_path有写权限为真
-x 有执行权限为真 [ -x file_path ]file_path有执行权限为真
-s 文件存在且不为空为真 [-s file_path]file_path存在且不为空为真

布尔运算符

运算符 描述 实例
非关系,条件结果取反 [ ! 1 -eq 2 ]为true
-a 和关系,在[]表达式中使用 [ 1 -eq 1 -a 2 -eq 2 ]为true,两者都为真才为真
-o 或关系,在[]表达式中使用 [ 1 -eq 1 -o 2 -eq 1 ]为true,两者有一真则为真

逻辑判断符

判断符 描述 实例
&& 逻辑和,在[[]]表达式中或判断表达式是否为真时使用 [[ 1 -eq 1 && 2 -eq 2 ]]为 true,[ 1 -eq 1 ] && echo ‘true’,如果&&前面的表达式为true则执行后面的
|| 逻辑或,在[[]]表达式中或判断表达式是否为真时使用 [[ 1 -eq 1

整数运算符

运算符 描述
+ 加法
减法
* 乘法
/ 除法
% 取余
运算表达式 实例
$(()) $((1+1))
$[] $[]

其他运算符

命令 描述 实例
let 赋值并运算 let x++;echo $x 每执行一次 x 加 1,let y–;echo $y 每执行一次 y 减 1,let x+=2 每执行一次 x 加 2,let x-=2 每执行一次 x 减 2
expr 乘法*需要\转义"*" expr 1 * 2 运算符两边必须有空格,expr( 1 + 2) * 2 使用双括号时要转义,

if语句

if语句用exit结束

单分支

if 条件表达式 ;then

    命令

fi
  • 实例:
#!/bin/bash
read -p "请输入数字" num
if [ $num -lt 10 ] ;then
        echo "${num}是数字两位数"
fi
...

╭─[email protected] ~  
╰─➤  bash test.sh
请输入数字3
3是数字一位数

多分支

if 条件表达式 ;then
    命令
else
    命令
fi

实例:

#!/bin/bash
read -p "请输入数字" num
if [ $num -gt 9 -a $num -lt 100 ] ;then
        echo "${num}是数字两位数"
else
        echo "${num}不是数字两位数"
fi
...

╭─[email protected] ~  
╰─➤  bash test.sh 
请输入数字56
56是数字两位数
╭─[email protected] ~  
╰─➤  bash test.sh
请输入数字222
222不是数字两位数

多分支

if 条件表达式 ;then
    命令
elif 条件表达式 ;then
    命令
else
    命令
fi

实例:

#!/bin/bash
num=`echo $RANDOM`
if [ $num -lt 1000 ];then
        echo "$num小于1000"
elif [ $num -ge 1000 -a $num -lt 2000 ];then
        echo "$num大于等于1000,小于2000"
elif [ $num -ge 2000 -a $num -lt 3000 ];then
        echo "$num大于等于2000,小于3000"
elif [ $num -ge 3000 -a $num -lt 4000 ];then
        echo "$num大于等于3000,小于4000"
else
        echo "$num大于等于4000"
fi
...
╭─[email protected] ~  
╰─➤  bash test.sh
24497大于等于4000
╭─[email protected] ~  
╰─➤  bash test.sh
20763大于等于4000

参考链接

发布了78 篇原创文章 · 获赞 25 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_37596943/article/details/103639230