-1

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:

  1. I need the prompt to display like it should pick Max_connections from testing.txt and max_connections=250 from diff.txt and server=00000000 from server.txt and ask for the below expected prompt.

  2. The same thing for second value Max_user_connections from texting.txt and Max_user_connections=300 from diff.txt and server=000000 from server.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
tripleee
  • 175,061
  • 34
  • 275
  • 318
Raj
  • 13
  • 3
  • 3
    Always first test your script to https://shellcheck.net before asking here. Thanks – Gilles Quénot Apr 30 '23 at 14:10
  • 2
    This is incorect: `if [ "$reply" == "yes" ] if [ "$reply" == "no" ]; then`. There are plenty of tutorials how you can do combined IF ORs or If ANDs, so you can refer to these tutorials to fix it. Again (you keep reporting this same Question) the Question should contain your exact error you need help with, along with what you have tried to fix this error... Both are not currently evident in your Q. Also to get the whole lines, not "one word" use `while` instead of `for` loop, again a lot of tutorials online on it – Ron Apr 30 '23 at 14:11
  • 1
    Indentation should be used for your code. It quickly highlights the scope of each flow control statement and makes it SO much easier to read and debug. I edited your question with that, that one is free :) – Nic3500 Apr 30 '23 at 23:55
  • 1
    Couple of points over what @Ron and @Gilles Quenot mentionned: **1** use `$( command)` instead of backticks. **2** you have a `for` missing its `do` **3** see https://mywiki.wooledge.org/BashFAQ/001 for how to implement loops that read from a file **4** `for var 2 in ...`, should be `for var2 in ...` IMHO. **5** Instead of `echo blabla; read`, you can use `read` to display the question itself. – Nic3500 May 01 '23 at 00:02
  • @GillesQuénot I have tested while loop script in shellcheck.net and found no errors in syntax,The problem is still with the prompt,Can you help me get the proper prompt. – Raj May 01 '23 at 08:11
  • @Nic3500 I tried using while loop but also still iam getting the same prompt. – Raj May 01 '23 at 08:14
  • Arev you trying to read through the two files in parallel (i.e. line 1 of both files, then line 2 of both files, etc)? If so, you need a single loop that reads from both files rather than two nested loops for the two files. See ["Read from two files line by line and process them simultaneously"](https://stackoverflow.com/questions/42694461/read-from-two-files-line-by-line-and-process-them-simultaneously), and Gilles' answer to ["Loop through the lines of two files in parallel"](https://unix.stackexchange.com/questions/82541/loop-through-the-lines-of-two-files-in-parallel/82710#82710) – Gordon Davisson May 01 '23 at 08:16

1 Answers1

0

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:

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
Nic3500
  • 8,144
  • 10
  • 29
  • 40