【问题标题】:How do I improve my logic to read and write variable values to a file?如何改进将变量值读取和写入文件的逻辑?
【发布时间】:2011-02-18 07:52:43
【问题描述】:

我在 shell 脚本中写入函数以从/向文件读取和写入变量设置。我想知道是否有更清洁的方法来做到这一点。我特别不喜欢删除现有匹配以进行写入然后在文件末尾重写的位。有一个更好的方法吗?谢谢。

fnReadTestSetting()
{
#$1 is the variable to be read from the testsettings.ini file
grep $1 $MAIN_FOLDER/testsettings.ini >$MAIN_FOLDER/temp.ini
if [ $? -eq 0 ]; then
    sed -i "s|$1=||" $MAIN_FOLDER/temp.ini
    TEST_VALUE=`cat $MAIN_FOLDER/temp.ini`
    export $1=$TEST_VALUE
fi
rm $MAIN_FOLDER/temp.ini
return
}


fnWriteTestSetting()
{
#$1 is the variable and value to be written to the testsettings.ini file in the format VARIABLE_NAME=VALUE
if [ ! -e $MAIN_FOLDER/testsettings.ini ]; then
    touch $MAIN_FOLDER/testsettings.ini
fi
SETTING_NAME=`echo $1 | awk -F = '{print $1}'`
grep $SETTING_NAME $MAIN_FOLDER/testsettings.ini &>/dev/null
if [ $? -eq 0 ]; then
    sed -i "/^$SETTING_NAME/d" $MAIN_FOLDER/testsettings.ini
    echo "$1" >> $MAIN_FOLDER/testsettings.ini

else
    echo "$1" >> $MAIN_FOLDER/testsettings.ini
fi
return
}

【问题讨论】:

  • 您可能希望使用${string#substring}$string 前面去除$substring 的最短匹配,而不是生成awk 以去除VARIABLE= 位;这里有一些小细节:tldp.org/LDP/abs/html/refcards.html
  • 我试过这个来阅读:LINE=grep $1 testsettings.ini;键=$1"=";价值=${LINE#$KEY};出口 $1=$VALUE;但是当我将 IP 传递给函数时它失败了,其值 IP_ADDRESS=10.0.0.1 写入 testsettings.ini

标签: bash file shell variables


【解决方案1】:

我做了一些改进:

您可以使用单个 sed 来读取设置。这节省了对 tmp 文件的写入。不知道您为什么要导出 1 美元。

fnReadTestSetting()
{
  #$1 is the variable to be read from the testsettings.ini file
  sed -n "s/^$1=\(.*$\)/\1/p" $MAIN_FOLDER/testsettings.ini 
}

对于写入,如果文件不存在,则无需触摸文件,因为无论如何都会创建它。您不需要 awk 来查找设置名称。您还可以将 grep 作为条件放在 if 语句中,而不是显式检查其退出代码。使用单个 sed 进行替换(而不是删除和回显)。

fnWriteTestSetting()
{
  #$1 is the variable and value to be written to the testsettings.ini file in the format VARIABLE_NAME=VALUE
  SETTING_NAME=${1%%=*}
  if grep -sq "^${SETTING_NAME}=" $MAIN_FOLDER/testsettings.ini
  then
    sed -i "s/^${SETTING_NAME}=.*$/$1/" $MAIN_FOLDER/testsettings.ini
  else
    echo "$1" >> $MAIN_FOLDER/testsettings.ini
  fi
  return
}

更新:

%%=* 删除 = 之后的所有内容。有关%% 运算符的更多信息,请查看string manipulation guide

${string%%substring} 删除时间最长 从后面匹配 $substring $字符串。

【讨论】:

  • 一些问题 1) 无论 $1 是否匹配,sed 都会返回退出状态 0。您是否认为有更好的方法来检查文件中是否定义了变量,而无需 grepping 文件中的“variable=”? 2) 你能解释一下 SETTING_NAME=${1%%=*} 是如何工作的吗?以前从未见过。谢谢。
  • 我不知道它的用途,但export 设置了$1 中保存的变量名的值。如您所知,declare 不能使用,因为这会使变量成为函数的本地变量,而eval 存在安全风险。 a=':;pwd;: '; eval $a=foo 评估 pwd(可能是恶意的)。 declareexport 会产生错误,因此更安全。刚刚发布的 Bash 4.2 有 declare -g 用于在函数内部声明全局变量。我以前没见过这个export 把戏。一个副作用是在某些情况下可能不需要导出。
【解决方案2】:

实际上没有必要在临时文件上使用sed -i,因为无论如何您都可以使用 sed 将您设置为变量的字符串返回。另外,我不相信您的正则表达式会占用等号两侧的空间,这在 .ini 文件(http://en.wikipedia.org/wiki/INI_file)中通常是允许的。正则表达式仍然很干净,不写入临时文件更干净,因为它使读取函数没有副作用。

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 2012-04-13
    • 1970-01-01
    • 2023-02-18
    • 2012-09-15
    • 1970-01-01
    相关资源
    最近更新 更多