Issue
I am modifying a mysql configuration file based on the differences between two files (source and target mysql configuration files) which will be generated in diff.txt
file and i will search the values present in testing.txt
to comment them in target mysql configuration file before adding the values present in diff.txt
.
In the code I have given prompt in a for
loop to print confirmation before proceeding to add the values, but prompt is not working properly, it works only if there are single values in the below files.
diff command used:diff target_my.cnf source_my.cnf | grep '>' | sed 's/> *//' > diff.txt
diff.txt
has the following contents:
Max_connections=250
Max_user_connections=300
server.txt
has server names
00000000
testing.txt
has the following
Max_connections
Max_user_connections
Need to achieve:
I need the prompt to display like it should pick
Max_connections
fromtesting.txt
andmax_connections=250
fromdiff.txt
andserver=00000000
fromserver.txt
and ask for the below expected prompt.The same thing for second value
Max_user_connections
fromtexting.txt
andMax_user_connections=300
fromdiff.txt
andserver=000000
fromserver.txt
and ask for the below prompt and end there it self. But in my case I m not getting proper prompt.
Expected prompt statement:
Do you want to comment env(max_user_connections) and add (max_user_connections=300) in server(0000000) after verifying? [yes/no]
Do you want to comment env(max_connections) and add (max_connections=250)in server(0000000) after verifying? [yes/no]
But as per my code it is displaying prompt like the below in a scattered way:
Do you want to comment env(max_user_connections) and add (max_user_connections=300) in server(0000000) after verifying? [yes/no]
Do you want to comment env(max_connections) and add (max_user_connections=300) in server(0000000) after verifying? [yes/no]
Do you want to comment env(max_user_connections) and add (max_connections=250) in server(0000000) after verifying? [yes/no]
Do you want to comment env(max_connections) and add (max_connections=250) in server(0000000) after verifying? [yes/no]
Need help in getting the prompt right so that I can modify the configuration file.
Code used:
function ask{
question="$1"
ok=0
while [ $ok -eq 0 ]; do
read -p " $question [yes/no] " reply
if [ "$reply" == "yes" ] || [ "$reply" == "no" ]; then
ok=1
done
echo -n "$reply"
}
for server in `cat server.txt`
do
for var in `cat diff.txt`
do
var1=$(sed "/=[^=]*$//g" diff.txt)
echo "$var1" > testing.txt
for var2 in `cat testing.txt`
reply=$(ask "do you want to comment($var2) and add($var) for server($server?")
if [ "$reply" == "yes" ]; then
sed -i "s/^${var1}/#&/" target_my.cnf
sed -i "/^#${var1}/a ${var}" target_my.cnf
else
echo -e "Skipping"
fi
done
done
done
Other method tried:
for server in `cat server.txt`
do
for var in `cat diff.txt`
do
var1=$(sed "/=[^=]*$//g" diff.txt)
echo "$var1" > testing.txt
for var2 in `cat testing.txt`
echo "do you want to comment($var2) and add($var) for server($server?")
read -r reply
if [ "$reply" == "yes" ]; then
sed -i "s/^${var1}/#&/" target_my.cnf
sed -i "/^#${var1}/a ${var}" target_my.cnf
else
echo -e "Skipping"
fi
done
done
done
Tried using while loop also but the same prompt is coming up:
while read -r server ; do
while read -r var ; do
While read -r var2 ; do
echo -e "do you want to comment${var2} and add${var} for server${server}?"
read -r reply < /dev/tty
if [ "$reply" == "yes" ]; then
sed -i "s/^${var1}/#&/" target_my.cnf
sed -i "/^#${var1}/a ${var}" target_my.cnf
else
echo -e "Skipping"
fi
done < documented.txt
done < testing.txt
done < server_my.cnf.txt
Solution
After looking at this question further, I think I understand your requirement. Here is a solution I came up with.
Assuming Testing.txt contains:
Max_connections
Max_user_connections
diff.txt contains:
Max_connections=250
Max_user_connections=300
server.txt contains:
00000000
11111111
This code will loop through the servers, loop through the variables to modify (listed in Testing.txt) and get the new values from diff.txt:
#!/bin/bash
while IFS= read -u 3 -r server
do
printf '\nDEBUG: server=%s\n' "$server"
while IFS= read -u 4 -r variable
do
printf ' DEBUG: var=%s\n' "$variable"
newvalue=$(grep "$variable" diff.txt)
read -e -r -p " Do you want to comment >>$variable<< and add >>$newvalue<< for server >>$server<<? [yes|no] " reply
printf ' DEBUG: reply=%s\n' "$reply"
printf ' --> here put the modification to your target_my.cnf code\n\n'
done 4< Testing.txt
done 3< server.txt
Explanations:
- The
while
method is from https://mywiki.wooledge.org/BashFAQ/001. - About the
read -u 3 -r server
andread -u 4 -r variable
. That is taken from BASH solution to embedded read -p within a while read loop. Each read must use its own file handler, otherwise theread
inside the secondwhile
will read from the files, and not from the terminal. read -e
: reads a line from the terminal.read -r
: related to backslashes, read https://ss64.com/bash/read.html.read -p
: no need for a separateecho
orprintf
,read
does this for you.newvalue
can be made more complicated if you only need the value, and not the entire line.
When I run this code, I get the following output:
./so.bash
DEBUG: server=00000000
DEBUG: var=Max_connections
Do you want to comment >>Max_connections<< and add >>Max_connections=250<< for server >>00000000<<? [yes|no] yes
DEBUG: reply=yes
--> here put the modification to your target_my.cnf code
DEBUG: var=Max_user_connections
Do you want to comment >>Max_user_connections<< and add >>Max_user_connections=300<< for server >>00000000<<? [yes|no] no
DEBUG: reply=no
--> here put the modification to your target_my.cnf code
DEBUG: server=11111111
DEBUG: var=Max_connections
Do you want to comment >>Max_connections<< and add >>Max_connections=250<< for server >>11111111<<? [yes|no] yes
DEBUG: reply=yes
--> here put the modification to your target_my.cnf code
DEBUG: var=Max_user_connections
Do you want to comment >>Max_user_connections<< and add >>Max_user_connections=300<< for server >>11111111<<? [yes|no] no
DEBUG: reply=no
--> here put the modification to your target_my.cnf code
Answered By - Nic3500 Answer Checked By - David Goodson (WPSolving Volunteer)