noober
noober

Reputation: 1505

bash scripting - while loop not reading next line and storing value as intended

I can't figure out why my while loop construct with these embedded if statements is not working. I have a file called source.txt

mmsGroupId=5ab5c0e04eff45274ce5e471
mmsApiKey=5ab5c22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a

I want my bash script to compare the local values (i.e. mmsGroupId and mmsApiKey) stored in a configuration file (which i use a sed replace). Initially, the local config file will have no value for the keys, so it would look like this test.config.

mmsGroupId=
mmsApiKey=

If the keys are empty and don't match, then replace the local values with the ones source.txt.

There will also be the case if the mmsGroupId, mmsApiKey will also have old values and I want to replace that with what's in the source file

mmsGroupId=123456789
mmsApiKey=123456789abcdefghijklmnopqrstuvwxyz

I'm using a while loop to read the 2 lines in the source.txt file, however I'm only getting the first line's (mmsGroupId) and not the (mmsApiKey).

Result:

mmsGroupId=5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a
mmsApiKey=5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a

Expecting: (note: there's more to this configuration file - i'm just showing the expected key=value that i'm expecting )

mmsGroupId=5ab5c0e04eff45274ce5e471
mmsApiKey=5ab5c22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a

So far my script looks like this:

#!/bin/bash

set -x

KEY=/tmp/source.txt

IFS='='
while read keyname value;
do
  echo "This is the mmsGroupId:$value"
  curr_group=$(grep mmsGroupId /tmp/test.config | cut -d "=" -f2);
  echo "This is the current mmsGroupId:$curr_group"
  if [[ "$keyname" = "mmsGroupId" && "$value" = "$curr_group" ]]; then
    echo "We have a match - $value:$curr_group - NOTHING TO DO"
  else
    echo "No match found - let us update it"
    sed -i 's/mmsGroupId='"$curr_group"'/mmsGroupId='"$value"'/g' /tmp/test.config
  fi
  echo "This is the mmsApiKey:$value"
  curr_apikey=$(grep mmsApiKey /tmp/test.config | cut -d "=" -f2);
  echo "This is the current mmsApiKey:$curr_apikey"
  if [[ "$keyname" = "mmsApiKey" && "$value" = "$curr_apikey" ]]; then
    echo "We have a match - $value:$curr_apikey - NOTHING TO DO"
  else
    echo "No match found - let us update it"
    sed -i 's/mmsApiKey='"$curr_apikey"'/mmsApiKey='"$value"'/g' /tmp/test.config
  fi
done < "$KEY"

set +x

Here's the debug log:

+ KEY=/tmp/OpsManagerKeys.txt
+ IFS==
+ read keyname value
+ echo 'This is the mmsGroupId:5bc5e0e04eff45274ce5e471'
This is the mmsGroupId:5bc5e0e04eff45274ce5e471
++ grep mmsGroupId /tmp/test.config
++ cut -d = -f2
+ curr_group=
+ echo 'This is the current mmsGroupId:'
This is the current mmsGroupId:
+ [[ mmsGroupId = \m\m\s\G\r\o\u\p\I\d ]]
+ [[ 5bc5e0e04eff45274ce5e471 = '' ]]
+ echo 'No match found - let us update it'
No match found - let us update it
+ sed -i s/mmsGroupId=/mmsGroupId=5bc5e0e04eff45274ce5e471/g /tmp/test.config
+ echo 'This is the mmsApiKey:5bc5e0e04eff45274ce5e471'
This is the mmsApiKey:5bc5e0e04eff45274ce5e471
++ grep mmsApiKey /tmp/test.config
++ cut -d = -f2
+ curr_apikey=
+ echo 'This is the current mmsApiKey:'
This is the current mmsApiKey:
+ [[ mmsGroupId = \m\m\s\A\p\i\K\e\y ]]
+ echo 'No match found - let us update it'
No match found - let us update it
+ sed -i s/mmsApiKey=/mmsApiKey=5bc5e0e04eff45274ce5e471/g /tmp/test.config
+ read keyname value
+ echo 'This is the mmsGroupId:5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a'
This is the mmsGroupId:5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a
++ grep mmsGroupId /tmp/test.config
++ cut -d = -f2
+ curr_group=5bc5e0e04eff45274ce5e471
+ echo 'This is the current mmsGroupId:5bc5e0e04eff45274ce5e471'
+ echo 'This is the current mmsGroupId:5bc5e0e04eff45274ce5e471'
This is the current mmsGroupId:5bc5e0e04eff45274ce5e471
+ [[ mmsApiKey = \m\m\s\G\r\o\u\p\I\d ]]
+ echo 'No match found - let us update it'
No match found - let us update it
+ sed -i s/mmsGroupId=5bc5e0e04eff45274ce5e471/mmsGroupId=5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a/g /tmp/test.config
+ echo 'This is the mmsApiKey:5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a'
This is the mmsApiKey:5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a
++ grep mmsApiKey /tmp/test.config
++ cut -d = -f2
+ curr_apikey=5bc5e0e04eff45274ce5e471
+ echo 'This is the current mmsApiKey:5bc5e0e04eff45274ce5e471'
This is the current mmsApiKey:5bc5e0e04eff45274ce5e471
+ [[ mmsApiKey = \m\m\s\A\p\i\K\e\y ]]
+ [[ 5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a = \5\b\c\5\e\0\e\0\4\e\f\f\4\5\2\7\4\c\e\5\e\4\7\1 ]]
+ echo 'No match found - let us update it'
No match found - let us update it
+ sed -i s/mmsApiKey=5bc5e0e04eff45274ce5e471/mmsApiKey=5cc5e22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a/g /tmp/test.config
+ read keyname value
+ set +x

Upvotes: 0

Views: 570

Answers (2)

that other guy
that other guy

Reputation: 123410

The issue is that you do the replacements on the wrong key. In this if statement

if [[ "$keyname" = "mmsGroupId" && "$value" = "$curr_group" ]]; then
    echo "We have a match - $value:$curr_group - NOTHING TO DO"
  else
    echo "No match found - let us update it"
    sed -i 's/mmsGroupId='"$curr_group"'/mmsGroupId='"$value"'/g' /tmp/test.config
  fi

The else block was supposed to run when the value in the file is incorrect, but it also runs when the $keyname is wrong.

You could use nested if statements or elif [[ "$keyname" = "mmsGroupId ]] to ensure that the replacement doesn't run on the wrong key.

A better solution is to get rid of the while loop and if statements:

for key in mmsGroupId mmsApiKey
do
  value=$(grep "$key" /tmp/source.txt | cut -d "=" -f2);
  sed -i "s/$key=.*/$key=$value/" /tmp/test.config
done

Upvotes: 1

Colin Moreno Burgess
Colin Moreno Burgess

Reputation: 1602

I think you should distinguish operations depending which key:value you are using in your loop, example:

#!/bin/bash

function subst
{
  echo "This is the $keyname:$value"
  curr_value=$(grep $keyname test.config | cut -d "=" -f2);
  echo "This is the current $keyname:$curr_value"
}


#set -x

KEY=source.txt

IFS='='
while read -r keyname value;
do
  if [[ $keyname = 'mmsGroupId' ]]
    then
      echo "do group things function"
      subst
    else
      echo "do apikey things function"
      subst
  fi
done < "$KEY"

Having added function for substitution simplifies code reusability.

# bash test.sh 
do group things function
This is the mmsGroupId:5ab5c0e04eff45274ce5e471
This is the current mmsGroupId:testconfiggroupvalueXXX
do apikey things function
This is the mmsApiKey:5ab5c22c4eff45274ce5e63f07536eddebedec576b0e02904deb001a
This is the current mmsApiKey:testconfigaplikeyvalueXXX

Upvotes: 2

Related Questions