博客主页:https://tomcat.blog.csdn.net
博主昵称:农民工老王
主要领域:Java、Linux、K8S
期待大家的关注💖点赞👍收藏⭐留言💬
故障详情
最近在工作过程中需要完成一个任务:检测某属性文件中的所有键值对,在其仅剩下VERSION有值时,或者全部键都没有值时,删除整个属性文件。
属性文件示例(下面的属性文件为我本人随意撰写,不代表任何实际意义,没有在实际工作中出现):
#Fri Oct 21 20:01:16 CST 2022 .bj88.test.cn.properties
VERSION=6.5.1
ENGINE_HOME=
LAOWANG_INSTALL_DIR=/home/test/laowang
DEVKIT_HOME=
我写的shell脚本:
#!/bin/bash
needDeletePro=1
checkPopertiesFilePath="${HOME}/.bj88.test.cn.properties"
awk -F"=" '{print $2}' $checkPopertiesFilePath| while read line
do
lineNumStr=$(echo ${line} | wc -L)
lineNum=$((${lineNumStr}))
if [ $lineNum -gt 1 ] && [ ${line} != "6.5.1" ] ; then
needDeletePro=0
break
fi
done
if [ $needDeletePro -eq 1 ]; then
rm -rf $checkPopertiesFilePath
fi
我的思路是,默认是要删除整个属性文件,但是如果检测到有值不为空和6.5.1就取消删除。
但是,整个脚本没有达到我想要的目的,任何情况下,都会执行删除操作。
问题原因
使用管道符 | 的方法会另外启动一个独立的子进程,因此循环中的变量needDeletePro仅在子进程中有效,与第二行的needDeletePro虽然同名,但不是同一个变量。
解决办法
用文件存储值
文件系统是相通的,可以借此传递值。
#!/bin/bash
tempText=$(mktemp)
echo 1 >$tempText
checkPopertiesFilePath="${HOME}/.bj88.test.cn.properties"
awk -F"=" '{print $2}' $checkPopertiesFilePath| while read line
do
lineNumStr=$(echo ${line} | wc -L)
lineNum=$((${lineNumStr}))
if [ $lineNum -gt 1 ] && [ ${line} != "6.5.1" ]; then
echo 0 >$tempText
break
fi
done
if [ `cat $tempText` -eq 1 ]; then
rm -rf $checkPopertiesFilePath
fi
使用重定向
重定向不会创建子进程。
#!/bin/bash
needDeletePro=1
checkPopertiesFilePath="${HOME}/.bj88.test.cn.properties"
while read line
do
lineValue=`echo $line | awk -F"=" '{print $2}'`
lineNumStr=$(echo ${lineValue} | wc -L)
lineNum=$((${lineNumStr}))
if [ $lineNum -gt 1 ] && [ ${lineValue} != "6.5.1" ]; then
needDeletePro=0
break
fi
done< $checkPopertiesFilePath
if [ $needDeletePro -eq 1 ]; then
rm -rf $checkPopertiesFilePath
fi
总结
while read
有坑,使用要谨慎。
如需转载,请注明本文的出处:农民工老王的CSDN博客https://blog.csdn.net/monarch91 。